Aeson / text-iso8601 have a vulnerability, let's update bounds

TLDR: If you depend on aeson, please bump your upper bound to <2.4.

For folks who have been confused about this, like me:

aeson 2.3.0.0 (2026-05-21) fixes HSEC-2026-0007, a remotely-triggerable memory-exhaustion DoS. It also requires text-iso8601 >= 0.2, fixing the second half of that advisory.

The packages still capped at <2.3 are collectively holding the ecosystem to versions with a published denial-of-service advisory. [for 3 months and counting.]

Two things that might unstick this:

  1. You don’t need to wait for your dependencies. Widen your <2.3 to <2.4; any package can do it today, in any order. Some of us may have assumed we’re blocked when we aren’t.
  2. Could the Hackage trustees bulk-revise these upper bounds? Security-motivated revisions are a thing they can do, and this would be much faster than waiting for so many maintainers to cut releases.

I didn’t realise that my packages were part of the problem. I’ve now bumped hledger, hledger-lib, hledger-ui and hledger-web to <2.4. I’ve kept the lower bounds unchanged to avoid dependency conflicts and stay installable from current snapshots.

I was thinking I should raise the aeson lower bound to >=2.3 to avoid the bug. But that would evict me from current stackage; and, bounds should express API compatibility, not security policy. Apparently the right way is to check that as a separate step with cabal-audit. Though I’m not sure if that reliably helps ordinary cabal users doing “cabal install PROGRAM”.

More info:

We had an excellent security advisory but we’ve failed at executing the fix across the ecosystem.

[Update: happily, the fix has now been backported to aeson-2.2.5.1 / text-iso8601-0.1.1.2, which will also help reduce the number of people exposed to the bug.]

5 Likes

Why wasn’t this a minor version bump? And why not backport it as 2.2.5.1 or 2.2.6?

I see it is listed as a “breaking change” in the changelog, but I would be very surprised if it breaks any code in practice and the behaviour was underspecified anyway. Nobody had a reason to expect such huge negative exponents to work.

Furthermore, I feel like using a better function than realToFrac could also solve the problem without breaking anything. For example, converting a Scientific to a Fixed a should be possible even for huge exponents. For the one problematic case where we need to convert Scientific -> Ratio a there was already a proper check even on the negative exponent.

We can and should at least add a warning to the Real Scientific instance: Add warnings about large exponents to Real and RealFrac by noughtmare · Pull Request #107 · basvandijk/scientific · GitHub

7 Likes

I see it is listed as a “breaking change” in the changelog, but I would be very surprised if it breaks any code in practice and the behaviour was underspecified anyway. Nobody had a reason to expect such huge negative exponents to work.

This makes sense. I now think I was too conservative in classifying this as a breaking change. So I’ll backport the fix to make the upgrade easier.

9 Likes

I’ve released the backports:

These releases include only changes related to the DoS vulnerability.

The other changes in aeson 2.3 were quite minor as well, but non-security related, hence I’ve left them out of the backport just in case, and you can still upgrade aeson to 2.3 if you really need them.

17 Likes

again, it would be nice to have hackage be able to broadcast vulnerable versions to guide the solver away from them unless the user opts in to vulnerable code

3 Likes