hsec-2026-0007
Vulnerability from osv_haskell
Published
2026-05-22 07:02
Modified
2026-05-22 07:02
Summary
Denial of Service and Memory Exhaustion in aeson and text-iso8601
Details

Denial of Service and Memory Exhaustion in aeson and text-iso8601

Two 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.

1. withBoundedScientific_ DoS / Memory Exhaustion (aeson)

A 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 > 1024) but fails to reject arbitrarily large negative exponents.

When 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.

Affected FromJSON instances:

  • Fixed a (including Centi, Pico, Nano, etc.)
  • NominalDiffTime
  • DiffTime

2. parseYear_ DoS / Memory Exhaustion (text-iso8601)

A 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.

The 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.

Affected FromJSON instances (via aeson):

  • Day
  • UTCTime
  • LocalTime
  • ZonedTime
  • TimeOfDay
  • Month
  • Quarter

Resolution

These issues were resolved by introducing proper bounds checks:

  1. aeson now applies an absolute bounds check to both positive and negative exponents (abs exp10 > 1024).
  2. text-iso8601 now enforces an upper bound limit on the number of year digits accepted by parseYear_.

Users are strongly advised to update to the patched versions:

  • aeson-2.3.0.0 or later
  • text-iso8601-0.2.0.0 or later

Acknowledgements

The vulnerabilities were reported Nathan Walsh, and patched by Li-yao Xia.


{
  "affected": [
    {
      "database_specific": {
        "human_link": "https://github.com/haskell/security-advisories/tree/main/advisories/published/2026/HSEC-2026-0007.md",
        "osv": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2026/HSEC-2026-0007.json"
      },
      "package": {
        "ecosystem": "Hackage",
        "name": "aeson"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.12.0.0"
            },
            {
              "fixed": "2.3.0.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "severity": [
        {
          "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
          "type": "CVSS_V3"
        }
      ]
    },
    {
      "database_specific": {
        "human_link": "https://github.com/haskell/security-advisories/tree/main/advisories/published/2026/HSEC-2026-0007.md",
        "osv": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2026/HSEC-2026-0007.json"
      },
      "package": {
        "ecosystem": "Hackage",
        "name": "text-iso8601"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.1"
            },
            {
              "fixed": "0.2.0.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "severity": [
        {
          "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
          "type": "CVSS_V3"
        }
      ]
    }
  ],
  "database_specific": {
    "home": "https://github.com/haskell/security-advisories",
    "osvs": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export",
    "repository": "https://github.com/haskell/security-advisories"
  },
  "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`\u0027s `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\u0027s 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",
  "id": "HSEC-2026-0007",
  "modified": "2026-05-22T07:02:58Z",
  "published": "2026-05-22T07:02:58Z",
  "references": [
    {
      "type": "FIX",
      "url": "https://github.com/haskell/aeson/commit/4e286806524702b562efbb36aa04ec976ec8fb90"
    },
    {
      "type": "FIX",
      "url": "https://github.com/haskell/aeson/commit/42775f45ff8dad934d44617f6f38ee874e1c9df1"
    }
  ],
  "schema_version": "1.5.0",
  "summary": "Denial of Service and Memory Exhaustion in aeson and text-iso8601"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…