hsec-2026-0011
osv_haskell# Superlinear encoding of numbers with large coefficients Encoding (pretty-printing) a `Scientific` number whose coefficient has many digits took time quadratic in the number of digits: the decimal digits were extracted by repeatedly dividing the whole coefficient by 10, once per digit. The `Show` instance, `Data.Text.Lazy.Builder.Scientific` and `Data.ByteString.Builder.Scientific` — which `aeson` uses to encode JSON numbers — all share this code path. A number with one million digits took about a minute to show, and about a tenth of a second after the fix. This is a denial-of-service risk for applications that decode numbers from an untrusted source and encode them again, e.g. JSON proxies, loggers or API gateways built on `aeson`. ## Resolution `scientific-0.3.9.0` reimplemented `normalize` and `toDecimalDigits` (the digit-extraction primitive) to be practically linear in the coefficient size. Note that `scientific-0.3.9.0` introduced a regression of its own; see HSEC-2026-0012. Upgrade directly to `scientific-0.3.10.0` or later, which fixes both issues. ## Credits Reported by Andrzej Rybczak (@arybczak); fixed by Oleg Grenrus (@phadej).
- Published
- unknown
- Last Modified
- unknown
CVSS details not available.
No product information available.
No linked vulnerabilities found.
{
"affected": [
{
"database_specific": {
"human_link": "https://github.com/haskell/security-advisories/tree/main/advisories/published/2026/HSEC-2026-0011.md",
"osv": "https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2026/HSEC-2026-0011.json",
"source": "https://github.com/haskell/security-advisories/blob/generated/osv-export/2026/HSEC-2026-0011.json"
},
"package": {
"ecosystem": "Hackage",
"name": "scientific",
"purl": "pkg:hackage/scientific"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.3.9.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.0.0.0",
"0.0.0.1",
"0.0.0.2",
"0.1.0.0",
"0.1.0.1",
"0.2.0.0",
"0.2.0.1",
"0.2.0.2",
"0.3.0.0",
"0.3.0.1",
"0.3.0.2",
"0.3.1.0",
"0.3.2.0",
"0.3.2.1",
"0.3.2.2",
"0.3.3.0",
"0.3.3.1",
"0.3.3.2",
"0.3.3.3",
"0.3.3.4",
"0.3.3.5",
"0.3.3.6",
"0.3.3.7",
"0.3.3.8",
"0.3.4.0",
"0.3.4.1",
"0.3.4.10",
"0.3.4.11",
"0.3.4.12",
"0.3.4.13",
"0.3.4.14",
"0.3.4.15",
"0.3.4.2",
"0.3.4.3",
"0.3.4.4",
"0.3.4.5",
"0.3.4.6",
"0.3.4.7",
"0.3.4.8",
"0.3.4.9",
"0.3.5.0",
"0.3.5.1",
"0.3.5.2",
"0.3.5.3",
"0.3.6.0",
"0.3.6.1",
"0.3.6.2",
"0.3.7.0",
"0.3.8.0",
"0.3.8.1"
]
}
],
"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": "# Superlinear encoding of numbers with large coefficients\n\nEncoding (pretty-printing) a `Scientific` number whose coefficient has many\ndigits took time quadratic in the number of digits: the decimal digits were\nextracted by repeatedly dividing the whole coefficient by 10, once per digit.\nThe `Show` instance, `Data.Text.Lazy.Builder.Scientific` and\n`Data.ByteString.Builder.Scientific` — which `aeson` uses to encode JSON\nnumbers — all share this code path. A number with one million digits took\nabout a minute to show, and about a tenth of a second after the fix.\n\nThis is a denial-of-service risk for applications that decode numbers from an\nuntrusted source and encode them again, e.g. JSON proxies, loggers or API\ngateways built on `aeson`.\n\n## Resolution\n\n`scientific-0.3.9.0` reimplemented `normalize` and `toDecimalDigits` (the\ndigit-extraction primitive) to be practically linear in the coefficient size.\n\nNote that `scientific-0.3.9.0` introduced a regression of its own; see\nHSEC-2026-0012. Upgrade\ndirectly to `scientific-0.3.10.0` or later, which fixes both issues.\n\n## Credits\n\nReported by Andrzej Rybczak (@arybczak); fixed by Oleg Grenrus (@phadej).\n",
"id": "HSEC-2026-0011",
"modified": "2026-11-03T22:45:02.729867511Z",
"published": "2026-11-03T22:32:58Z",
"references": [
{
"type": "REPORT",
"url": "https://github.com/basvandijk/scientific/pull/109"
},
{
"type": "FIX",
"url": "https://github.com/basvandijk/scientific/pull/116"
},
{
"type": "FIX",
"url": "https://github.com/basvandijk/scientific/pull/117"
},
{
"type": "DISCUSSION",
"url": "https://www.reddit.com/r/haskell/comments/1xbj59g/dont_use_scientific_for_calculations_it_can/"
}
],
"related": [
"HSEC-2026-0012"
],
"schema_version": "1.9.2",
"summary": "Superlinear encoding of numbers with large coefficients"
}