hsec-2023-0007

osv_haskell
Description

# `readFloat`: memory exhaustion with large exponent `Numeric.readFloat` takes time and memory linear in the size of the number _denoted_ by the input string. In particular, processing a number expressed in scientific notation with a very large exponent could cause a denial of service. The slowdown is observable on a modern machine running GHC 9.4.4: ``` ghci> import qualified Numeric ghci> Numeric.readFloat "1e1000000" -- near instantaneous [(Infinity,"")] ghci> Numeric.readFloat "1e10000000" -- perceptible pause [(Infinity,"")] ghci> Numeric.readFloat "1e100000000" -- ~ 3 seconds [(Infinity,"")] ghci> Numeric.readFloat "1e1000000000" -- ~ 35 seconds [(Infinity,"")] ``` ## In *base* `Numeric.readFloat` is defined for all `RealFrac a => a`: ```haskell readFloat :: RealFrac a => ReadS a ``` The `RealFrac` type class does not express any bounds on the size of values representable in the types for which instances exist, so bounds checking is not possible (in this *generic* function). `readFloat` uses to `Text.Read.Lex.numberToRational` which, among other things, calculates `10 ^ exponent`, which seems to take linear time and memory. **Mitigation:** use `read`. The `Read` instances for `Float` and `Double` perform bounds checks on the exponent, via `Text.Read.Lex.numberToRangedRational`. ## In *toml-reader* The issue was detected in *toml-reader* version 0.1.0.0, and mitigated in version 0.2.0.0 by immediately returning `Infinity` when the exponent is large enough that there's no reason to process it.

Timeline
Published
unknown
Last Modified
unknown
CVSS Details

CVSS details not available.

Affected Products

No product information available.

References
Linked Vulnerabilities

No linked vulnerabilities found.

{
  "affected": [
    {
      "database_specific": {
        "human_link": "https://github.com/haskell/security-advisories/tree/main/advisories/published/2023/HSEC-2023-0007.md",
        "osv": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2023/HSEC-2023-0007.json",
        "source": "https://github.com/haskell/security-advisories/blob/generated/osv-export/2023/HSEC-2023-0007.json"
      },
      "package": {
        "ecosystem": "Hackage",
        "name": "base",
        "purl": "pkg:hackage/base"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "3.0.3.1"
            }
          ],
          "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"
        }
      ],
      "versions": [
        "3.0.3.1",
        "3.0.3.2",
        "4.0.0.0",
        "4.1.0.0",
        "4.10.0.0",
        "4.10.1.0",
        "4.11.0.0",
        "4.11.1.0",
        "4.12.0.0",
        "4.13.0.0",
        "4.14.0.0",
        "4.14.1.0",
        "4.14.2.0",
        "4.14.3.0",
        "4.15.0.0",
        "4.15.1.0",
        "4.16.0.0",
        "4.16.1.0",
        "4.16.2.0",
        "4.16.3.0",
        "4.16.4.0",
        "4.17.0.0",
        "4.17.1.0",
        "4.17.2.0",
        "4.17.2.1",
        "4.18.0.0",
        "4.18.1.0",
        "4.18.2.0",
        "4.18.2.1",
        "4.18.3.0",
        "4.19.0.0",
        "4.19.1.0",
        "4.19.2.0",
        "4.2.0.0",
        "4.2.0.1",
        "4.2.0.2",
        "4.20.0.0",
        "4.20.0.1",
        "4.20.1.0",
        "4.20.2.0",
        "4.21.0.0",
        "4.21.1.0",
        "4.21.2.0",
        "4.22.0.0",
        "4.3.0.0",
        "4.3.1.0",
        "4.4.0.0",
        "4.4.1.0",
        "4.5.0.0",
        "4.5.1.0",
        "4.6.0.0",
        "4.6.0.1",
        "4.7.0.0",
        "4.7.0.1",
        "4.7.0.2",
        "4.8.0.0",
        "4.8.1.0",
        "4.8.2.0",
        "4.9.0.0",
        "4.9.1.0"
      ]
    },
    {
      "database_specific": {
        "human_link": "https://github.com/haskell/security-advisories/tree/main/advisories/published/2023/HSEC-2023-0007.md",
        "osv": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2023/HSEC-2023-0007.json",
        "source": "https://github.com/haskell/security-advisories/blob/generated/osv-export/2023/HSEC-2023-0007.json"
      },
      "package": {
        "ecosystem": "Hackage",
        "name": "toml-reader",
        "purl": "pkg:hackage/toml-reader"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0.1.0.0"
            },
            {
              "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"
        }
      ],
      "versions": [
        "0.1.0.0"
      ]
    }
  ],
  "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": "# `readFloat`: memory exhaustion with large exponent\n\n`Numeric.readFloat` takes time and memory linear in the size of the\nnumber _denoted_ by the input string.  In particular, processing a\nnumber expressed in scientific notation with a very large exponent\ncould cause a denial of service.  The slowdown is observable on a\nmodern machine running GHC 9.4.4:\n\n```\nghci> import qualified Numeric\nghci> Numeric.readFloat \"1e1000000\"    -- near instantaneous\n[(Infinity,\"\")]\nghci> Numeric.readFloat \"1e10000000\"   -- perceptible pause\n[(Infinity,\"\")]\nghci> Numeric.readFloat \"1e100000000\"  -- ~ 3 seconds\n[(Infinity,\"\")]\nghci> Numeric.readFloat \"1e1000000000\" -- ~ 35 seconds\n[(Infinity,\"\")]\n```\n\n## In *base*\n\n`Numeric.readFloat` is defined for all `RealFrac a => a`:\n\n```haskell\nreadFloat :: RealFrac a => ReadS a\n```\n\nThe `RealFrac` type class does not express any bounds on the size of\nvalues representable in the types for which instances exist, so\nbounds checking is not possible (in this *generic* function).\n`readFloat` uses to `Text.Read.Lex.numberToRational` which, among\nother things, calculates `10 ^ exponent`, which seems to take linear\ntime and memory.\n\n**Mitigation:** use `read`.  The `Read` instances for `Float` and\n`Double` perform bounds checks on the exponent, via\n`Text.Read.Lex.numberToRangedRational`.\n\n\n## In *toml-reader*\n\nThe issue was detected in *toml-reader* version 0.1.0.0, and\nmitigated in version 0.2.0.0 by immediately returning `Infinity`\nwhen the exponent is large enough that there's no reason to process\nit.\n",
  "id": "HSEC-2023-0007",
  "modified": "2026-05-29T21:00:04.553436278Z",
  "published": "2025-11-14T14:45:34Z",
  "references": [
    {
      "type": "REPORT",
      "url": "https://gitlab.haskell.org/ghc/ghc/-/issues/23538"
    },
    {
      "type": "REPORT",
      "url": "https://github.com/brandonchinn178/toml-reader/issues/8"
    },
    {
      "type": "FIX",
      "url": "https://github.com/brandonchinn178/toml-reader/pull/9"
    }
  ],
  "schema_version": "1.7.5",
  "summary": "readFloat: memory exhaustion with large exponent"
}
View JSON API Download JSON