{"id":"CVE-2026-32686","aliases":["EEF-CVE-2026-32686","EUVD-2026-28376","GHSA-rhv4-8758-jx7v"],"status":"published","title":"Unbounded exponent in decimal enables unauthenticated DoS","description":"Uncontrolled Resource Consumption vulnerability in ericmj decimal allows unauthenticated remote Denial of Service.\n\nThe decimal library does not bound the exponent on parsed input. Storing a decimal with a very large exponent (e.g. Decimal.new(\"1e1000000000\")) is accepted without error. Subsequent calls to arithmetic functions (Decimal.add/2, Decimal.sub/2, Decimal.div/2M), Decimal.to_string/2M with :normalM or :xsdM format, Decimal.to_integer/1M, Decimal.round/3M, or Decimal.compare/3M with a threshold allocate memory proportional to the exponent value, which can exhaust available memory and crash the BEAM VM.\n\nAny application that accepts user-supplied decimal input and subsequently performs arithmetic, rounding, conversion to integer, or string formatting on it is exposed. A single malicious request is sufficient to cause an out-of-memory crash.\n\nThis issue affects decimal: from 0.1.0 before 3.0.0.","severity":{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00484,"percentile":0.42064,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-400"],"published":"2026-05-07T14:04:47Z","modified":"2026-10-28T02:31:02Z","fixes":[{"ecosystem":"Hex","package":"decimal","fixed_in":["3.0.0"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Hex","package":"decimal","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.1.0"},{"fixed":"3.0.0"}]}]},{"source":"osv","ecosystem":"Hex","package":"decimal","ranges":[{"type":"SEMVER","events":[{"introduced":"0.1.0"},{"fixed":"3.0.0"}]}],"versions":["0.1.1","0.1.2","0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","1.0.0","1.0.1","1.1.0","1.1.1","1.1.2","1.2.0","1.3.0","1.3.1","1.4.0","1.4.1","1.5.0","1.6.0","1.7.0","1.8.0","1.8.1","1.9.0","1.9.0-rc.0","2.0.0","2.0.0-rc.0","2.1.0","2.1.1","2.2.0","2.3.0","2.4.0","2.4.1"]},{"source":"osv","ecosystem":"Hex","package":"decimal","ranges":[{"type":"SEMVER","events":[{"introduced":"0.1.0"},{"fixed":"3.0.0"}]}],"versions":["0.1.1","0.1.2","0.2.0","0.2.1","0.2.2","0.2.3","0.2.4","0.2.5","1.0.0","1.0.1","1.1.0","1.1.1","1.1.2","1.2.0","1.3.0","1.3.1","1.4.0","1.4.1","1.5.0","1.6.0","1.7.0","1.8.0","1.8.1","1.9.0","1.9.0-rc.0","2.0.0","2.0.0-rc.0","2.1.0","2.1.1","2.2.0","2.3.0","2.4.0","2.4.1"]}],"products":[{"vendor":"ericmj","product":"decimal"}],"references":[{"url":"https://github.com/ericmj/decimal/security/advisories/GHSA-rhv4-8758-jx7v","tags":["vendor-advisory","related","exploit","advisory","web"]},{"url":"https://cna.erlef.org/cves/CVE-2026-32686.html","tags":["related","web"]},{"url":"https://osv.dev/vulnerability/EEF-CVE-2026-32686","tags":["related","web"]},{"url":"https://github.com/ericmj/decimal/commit/bc11f4a2b6fb61fc1360a0ab4e79141bba918841","tags":["related","fix","web"]},{"url":"https://github.com/ericmj/decimal/commit/6a523f3a73b8c9974540e21c7aa88f1258bb35ae","tags":["patch","fix","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-32686","tags":["advisory"]},{"url":"https://github.com/ericmj/decimal/releases/tag/v3.0.0","tags":["web"]},{"url":"https://github.com/ericmj/decimal/releases/tag/v2.4.0","tags":["web"]},{"url":"https://github.com/advisories/GHSA-rhv4-8758-jx7v"},{"url":"https://github.com","tags":["web"]},{"url":"https://repo.hex.pm","tags":["web"]},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/32xxx/CVE-2026-32686.json","tags":["advisory"]},{"url":"https://github.com/ericmj/decimal","tags":["package"]},{"url":"https://hex.pm/packages/decimal","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-32686","title":"Unbounded exponent in decimal enables unauthenticated DoS","description":"Uncontrolled Resource Consumption vulnerability in ericmj decimal allows unauthenticated remote Denial of Service.\n\nThe decimal library does not bound the exponent on parsed input. Storing a decimal with a very large exponent (e.g. Decimal.new(\"1e1000000000\")) is accepted without error. Subsequent calls to arithmetic functions (Decimal.add/2, Decimal.sub/2, Decimal.div/2M), Decimal.to_string/2M with :normalM or :xsdM format, Decimal.to_integer/1M, Decimal.round/3M, or Decimal.compare/3M with a threshold allocate memory proportional to the exponent value, which can exhaust available memory and crash the BEAM VM.\n\nAny application that accepts user-supplied decimal input and subsequently performs arithmetic, rounding, conversion to integer, or string formatting on it is exposed. A single malicious request is sufficient to cause an out-of-memory crash.\n\nThis issue affects decimal: from 0.1.0 before 3.0.0.","status":"published","published":"2026-05-07T14:04:47.222Z","modified":"2026-09-08T13:08:41.575Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium","assessor":"cna"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T14:19:57.47301Z"}],"euvd":[{"id":"EUVD-2026-28376","description":"Uncontrolled Resource Consumption vulnerability in ericmj decimal allows unauthenticated remote Denial of Service.\n\nThe decimal library does not bound the exponent on parsed input. Storing a decimal with a very large exponent (e.g. Decimal.new(\"1e1000000000\")) is accepted without error. Subsequent calls to arithmetic functions (Decimal.add/2, Decimal.sub/2, Decimal.div/2M), Decimal.to_string/2M with :normalM or :xsdM format, Decimal.to_integer/1M, Decimal.round/3M, or Decimal.compare/3M with a threshold allocate memory proportional to the exponent value, which can exhaust available memory and crash the BEAM VM.\n\nAny application that accepts user-supplied decimal input and subsequently performs arithmetic, rounding, conversion to integer, or string formatting on it is exposed. A single malicious request is sufficient to cause an out-of-memory crash.\n\nThis issue affects decimal: from 0.1.0 before 3.0.0.","status":"published","published":"2026-05-07T14:04:47Z","modified":"2026-09-08T13:08:41Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"updated_at":"2026-11-02T17:28:29.861344Z"}],"ghsa":[{"id":"GHSA-rhv4-8758-jx7v","title":"Decimal: Unbounded exponent in `Decimal.new` enables unauthenticated DoS","description":"Summary\n`decimal` doesn't bound the exponent on parsed input, so something like `\"1e10000000\"` is parsed fine but then explodes the memory to more than 7GB if you run e.g. `Decimal.add(Decimal.parse(\"1e10000000\"), 1)` because for positive `exp`, the function tail-recurses with `coef * 10` and `exp - 1` per iteration, growing the bignum coefficient by one digit each step. In the worst case, one request is enough to OOM the BEAM.\n\n### Details\n`Decimal.new/parse/cast` happily store huge exponents. After that, a bunch of core paths allocate proportional to `exp`:\n- `add/sub/div` go through `add_align`, which calls `pow10(exp1 - exp2)` and builds a giant bignum (lib/decimal.ex:1734-1738, 1827).\n- `to_string/2` with `:normal` (also `:xsd` and the `String.Chars` impl) does `:lists.duplicate(exp, ?0)` (lib/decimal.ex:1506, 1513).\n- `to_integer/1` recurses `coef * 10`, `exp - 1` once per unit of `exp` (lib/decimal.ex:1603-1605).\n- `round/3` does the same `:lists.duplicate` trick on the exp difference (lib/decimal.ex:1850, 1874).\n- `compare/3` with a threshold argument loops back into `add`/`sub`, so it's vulnerable too (lib/decimal.ex:331-332).\n\n### PoC\nAny of these will hang or OOM the BEAM:\n```elixir\nDecimal.add(Decimal.new(\"1\"), Decimal.new(\"1e1000000000\"))\nDecimal.to_string(Decimal.new(\"1e1000000000\"), :normal)\nDecimal.to_integer(Decimal.new(\"1e1000000000\"))\nDecimal.round(Decimal.new(\"1e1000000000\"))\n```\n\n### Impact\nUnauthenticated remote DoS. Anything that takes a user-supplied decimal (JSON, form field, Ecto `:decimal` field — basically everywhere) and then does arithmetic, rounding, `to_integer`, or `to_string` on it is exposed. One request can kill the node with a Out-of-Memory exception.\n\n### Note on the security fixes done in version 2.4.0\nWhile `2.4.0` has the changes to mitigate this issue it's not considered as a patched version because it doesn't have them enabled by default.","status":"published","published":"2026-05-12T15:09:20Z","modified":"2026-08-05T12:40:53Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T14:40:56.852119Z"}],"nvd":[{"id":"CVE-2026-32686","description":"Uncontrolled Resource Consumption vulnerability in ericmj decimal allows unauthenticated remote Denial of Service.\n\nThe decimal library does not bound the exponent on parsed input. Storing a decimal with a very large exponent (e.g. Decimal.new(\"1e1000000000\")) is accepted without error. Subsequent calls to arithmetic functions (Decimal.add/2, Decimal.sub/2, Decimal.div/2M), Decimal.to_string/2M with :normalM or :xsdM format, Decimal.to_integer/1M, Decimal.round/3M, or Decimal.compare/3M with a threshold allocate memory proportional to the exponent value, which can exhaust available memory and crash the BEAM VM.\n\nAny application that accepts user-supplied decimal input and subsequently performs arithmetic, rounding, conversion to integer, or string formatting on it is exposed. A single malicious request is sufficient to cause an out-of-memory crash.\n\nThis issue affects decimal: from 0.1.0 before 3.0.0.","status":"published","published":"2026-05-07T15:16:05.37Z","modified":"2026-10-26T20:10:00.16Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"medium","assessor":"secondary"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T14:12:17.842772Z"}],"osv":[{"id":"CVE-2026-32686","title":"Unbounded exponent in decimal enables unauthenticated DoS","description":"Uncontrolled Resource Consumption vulnerability in ericmj decimal allows unauthenticated remote Denial of Service.\n\nThe decimal library does not bound the exponent on parsed input. Storing a decimal with a very large exponent (e.g. Decimal.new(\"1e1000000000\")) is accepted without error. Subsequent calls to arithmetic functions (Decimal.add/2, Decimal.sub/2, Decimal.div/2M), Decimal.to_string/2M with :normalM or :xsdM format, Decimal.to_integer/1M, Decimal.round/3M, or Decimal.compare/3M with a threshold allocate memory proportional to the exponent value, which can exhaust available memory and crash the BEAM VM.\n\nAny application that accepts user-supplied decimal input and subsequently performs arithmetic, rounding, conversion to integer, or string formatting on it is exposed. A single malicious request is sufficient to cause an out-of-memory crash.\n\nThis issue affects decimal: from 0.1.0 before 3.0.0.","status":"published","published":"2026-05-07T14:04:47.222Z","modified":"2026-10-28T02:31:02.474659443Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T15:45:01.548715Z"},{"id":"EEF-CVE-2026-32686","title":"Unbounded exponent in decimal enables unauthenticated DoS","description":"## Summary\n\nUncontrolled Resource Consumption vulnerability in ericmj decimal allows unauthenticated remote Denial of Service.\n\nThe `decimal` library does not bound the exponent on parsed input. Storing a decimal with a very large exponent (e.g. `Decimal.new(\"1e1000000000\")`) is accepted without error. Subsequent calls to arithmetic functions (`Decimal.add/2`, `Decimal.sub/2`, `Decimal.div/2`M), `Decimal.to_string/2`M with `:normal`M or `:xsd`M format, `Decimal.to_integer/1`M, `Decimal.round/3`M, or `Decimal.compare/3`M with a threshold allocate memory proportional to the exponent value, which can exhaust available memory and crash the BEAM VM.\n\nAny application that accepts user-supplied decimal input and subsequently performs arithmetic, rounding, conversion to integer, or string formatting on it is exposed. A single malicious request is sufficient to cause an out-of-memory crash.\n\nThis issue affects decimal: from 0.1.0 before 3.0.0.","status":"published","published":"2026-05-07T14:04:47.222Z","modified":"2026-09-08T13:15:03.575002463Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T15:46:33.047032Z"},{"id":"GHSA-rhv4-8758-jx7v","title":"Decimal: Unbounded exponent in `Decimal.new` enables unauthenticated DoS","description":"Summary\n`decimal` doesn't bound the exponent on parsed input, so something like `\"1e10000000\"` is parsed fine but then explodes the memory to more than 7GB if you run e.g. `Decimal.add(Decimal.parse(\"1e10000000\"), 1)` because for positive `exp`, the function tail-recurses with `coef * 10` and `exp - 1` per iteration, growing the bignum coefficient by one digit each step. In the worst case, one request is enough to OOM the BEAM.\n\n### Details\n`Decimal.new/parse/cast` happily store huge exponents. After that, a bunch of core paths allocate proportional to `exp`:\n- `add/sub/div` go through `add_align`, which calls `pow10(exp1 - exp2)` and builds a giant bignum (lib/decimal.ex:1734-1738, 1827).\n- `to_string/2` with `:normal` (also `:xsd` and the `String.Chars` impl) does `:lists.duplicate(exp, ?0)` (lib/decimal.ex:1506, 1513).\n- `to_integer/1` recurses `coef * 10`, `exp - 1` once per unit of `exp` (lib/decimal.ex:1603-1605).\n- `round/3` does the same `:lists.duplicate` trick on the exp difference (lib/decimal.ex:1850, 1874).\n- `compare/3` with a threshold argument loops back into `add`/`sub`, so it's vulnerable too (lib/decimal.ex:331-332).\n\n### PoC\nAny of these will hang or OOM the BEAM:\n```elixir\nDecimal.add(Decimal.new(\"1\"), Decimal.new(\"1e1000000000\"))\nDecimal.to_string(Decimal.new(\"1e1000000000\"), :normal)\nDecimal.to_integer(Decimal.new(\"1e1000000000\"))\nDecimal.round(Decimal.new(\"1e1000000000\"))\n```\n\n### Impact\nUnauthenticated remote DoS. Anything that takes a user-supplied decimal (JSON, form field, Ecto `:decimal` field — basically everywhere) and then does arithmetic, rounding, `to_integer`, or `to_string` on it is exposed. One request can kill the node with a Out-of-Memory exception.\n\n### Note on the security fixes done in version 2.4.0\nWhile `2.4.0` has the changes to mitigate this issue it's not considered as a patched version because it doesn't have them enabled by default.","status":"published","published":"2026-05-12T15:09:20Z","modified":"2026-08-05T12:45:47.358985491Z","cvss":[{"version":"4.0","score":6.9,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"medium"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T15:46:55.877614Z"}]}}
