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.
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.
Reported by Andrzej Rybczak (@arybczak); fixed by Oleg Grenrus (@phadej).
{
"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"
}"https://github.com/haskell/security-advisories/tree/main/advisories/published/2026/HSEC-2026-0011.md"
"https://raw.githubusercontent.com/haskell/security-advisories/refs/heads/generated/osv-export/2026/HSEC-2026-0011.json"
"https://github.com/haskell/security-advisories/blob/generated/osv-export/2026/HSEC-2026-0011.json"