diff --git a/advisories/hackage/base/HSEC-2023-0007.md b/advisories/hackage/base/HSEC-2023-0007.md new file mode 100644 index 00000000..2cdd5d23 --- /dev/null +++ b/advisories/hackage/base/HSEC-2023-0007.md @@ -0,0 +1,82 @@ +```toml +[advisory] +id = "HSEC-2023-0007" +cwe = [1284, 789] +keywords = ["toml", "parser", "dos"] + +[[affected]] +package = "base" +cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" +[[affected.versions]] +# it was introduced earlier, but this is the earliest version on Hackage +introduced = "3.0.3.1" + +[[affected]] +package = "toml-reader" +cvss = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H" +[[affected.versions]] +introduced = "0.1.0.0" +fixed = "0.2.0.0" + +[[references]] +type = "REPORT" +url = "https://gitlab.haskell.org/ghc/ghc/-/issues/23538" +[[references]] +type = "REPORT" +url = "https://github.com/brandonchinn178/toml-reader/issues/8" +[[references]] +type = "FIX" +url = "https://github.com/brandonchinn178/toml-reader/pull/9" + +``` + +# `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. + +In version `0.1.0.0` of `toml-reader`, very large number literals +(scientific notation with large exponent) take time and memory +linear in the size of the number denoted. diff --git a/advisories/hackage/toml-reader/HSEC-2023-0007.md b/advisories/hackage/toml-reader/HSEC-2023-0007.md new file mode 120000 index 00000000..68d51e39 --- /dev/null +++ b/advisories/hackage/toml-reader/HSEC-2023-0007.md @@ -0,0 +1 @@ +../base/HSEC-2023-0007.md \ No newline at end of file