{"id":"HSEC-2026-0007","summary":"Denial of Service and Memory Exhaustion in aeson and text-iso8601","details":"# Denial of Service and Memory Exhaustion in aeson and text-iso8601\n\nTwo Denial of Service (DoS) and memory exhaustion vulnerabilities were identified in the `aeson` and `text-iso8601` packages. These vulnerabilities allow an attacker to exhaust server memory and crash the host process by supplying maliciously crafted JSON payloads.\n\n## 1. `withBoundedScientific_` DoS / Memory Exhaustion (`aeson`)\n\nA vulnerability exists in `aeson`'s `withBoundedScientific_` function (located in `src/Data/Aeson/Types/FromJSON.hs`). The exponent bounds check only rejects large positive exponents (`exp10 \u003e 1024`) but fails to reject arbitrarily large negative exponents.\n\nWhen an attacker sends a JSON number with a massive negative exponent (e.g., `1e-999999999`), the value bypasses the check and flows into `realToFrac`, which computes `fromRational . toRational`. For such a large negative exponent, `toRational` produces a GMP Integer with approximately 1 billion decimal digits, causing immediate and severe memory exhaustion.\n\nAffected `FromJSON` instances:\n\n* `Fixed a` (including `Centi`, `Pico`, `Nano`, etc.)\n* `NominalDiffTime`\n* `DiffTime`\n\n## 2. `parseYear_` DoS / Memory Exhaustion (`text-iso8601`)\n\nA second vulnerability exists in the `text-iso8601` library's year parser (`parseYear_` in `src/Data/Time/FromText.hs`), which `aeson` relies upon for all of its date/time `FromJSON` instances.\n\nThe year parser loops over digit characters with no upper bound constraint. The accumulated digits are then passed to `textToInteger`, which converts the arbitrarily long decimal string into a Haskell Integer (an arbitrary-precision bignum). Because this conversion is super-linear in the number of digits, an attacker can send a JSON date string with millions of digits in the year position (e.g., `{\"date\": \"999...999-01-01T00:00:00Z\"}`). A relatively small payload (~1MB) can cause seconds of CPU time and hundreds of megabytes of memory consumption, creating a practical asymmetric DoS vector.\n\nAffected `FromJSON` instances (via `aeson`):\n\n* `Day`\n* `UTCTime`\n* `LocalTime`\n* `ZonedTime`\n* `TimeOfDay`\n* `Month`\n* `Quarter`\n\n## Resolution\n\nThese issues were resolved by introducing proper bounds checks:\n\n1. `aeson` now applies an absolute bounds check to both positive and negative exponents (`abs exp10 \u003e 1024`).\n2. `text-iso8601` now enforces an upper bound limit on the number of year digits accepted by `parseYear_`.\n\nUsers are strongly advised to update to the patched versions:\n\n* `aeson-2.3.0.0` or later\n* `text-iso8601-0.2.0.0` or later\n\n## Acknowledgements\n\nThe vulnerabilities were reported Nathan Walsh, and patched by Li-yao Xia.\n","modified":"2026-05-22T07:15:04.180406539Z","published":"2026-05-22T07:02:58Z","database_specific":{"repository":"https://github.com/haskell/security-advisories","osvs":"https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export","home":"https://github.com/haskell/security-advisories"},"references":[{"type":"FIX","url":"https://github.com/haskell/aeson/commit/4e286806524702b562efbb36aa04ec976ec8fb90"},{"type":"FIX","url":"https://github.com/haskell/aeson/commit/42775f45ff8dad934d44617f6f38ee874e1c9df1"}],"affected":[{"package":{"name":"aeson","ecosystem":"Hackage","purl":"pkg:hackage/aeson"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.12.0.0"},{"fixed":"2.3.0.0"}]}],"versions":["1.0.0.0","1.0.1.0","1.0.2.0","1.0.2.1","1.1.0.0","1.1.1.0","1.1.2.0","1.2.0.0","1.2.1.0","1.2.2.0","1.2.3.0","1.2.4.0","1.3.0.0","1.3.1.0","1.3.1.1","1.4.0.0","1.4.1.0","1.4.2.0","1.4.3.0","1.4.4.0","1.4.5.0","1.4.6.0","1.4.7.0","1.4.7.1","1.5.0.0","1.5.1.0","1.5.2.0","1.5.3.0","1.5.4.0","1.5.4.1","1.5.5.0","1.5.5.1","1.5.6.0","2.0.0.0","2.0.1.0","2.0.2.0","2.0.3.0","2.1.0.0","2.1.1.0","2.1.2.0","2.1.2.1","2.2.0.0","2.2.1.0","2.2.2.0","2.2.3.0","2.2.4.0","2.2.4.1","2.2.5.0"],"database_specific":{"source":"https://github.com/haskell/security-advisories/blob/generated/osv-export/2026/HSEC-2026-0007.json","osv":"https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2026/HSEC-2026-0007.json","human_link":"https://github.com/haskell/security-advisories/tree/main/advisories/published/2026/HSEC-2026-0007.md"},"severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}]},{"package":{"name":"text-iso8601","ecosystem":"Hackage","purl":"pkg:hackage/text-iso8601"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.1"},{"fixed":"0.2.0.0"}]}],"versions":["0.1","0.1.1","0.1.1.1"],"database_specific":{"source":"https://github.com/haskell/security-advisories/blob/generated/osv-export/2026/HSEC-2026-0007.json","osv":"https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2026/HSEC-2026-0007.json","human_link":"https://github.com/haskell/security-advisories/tree/main/advisories/published/2026/HSEC-2026-0007.md"},"severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}]}],"schema_version":"1.7.5"}