May 12, 2026·6 min read·5 visits
Unbounded exponent parsing in ericmj/decimal allows remote attackers to crash the BEAM VM via OOM by supplying astronomical scientific notation values that trigger massive bignum allocations during arithmetic alignment.
The ericmj/decimal Elixir library suffers from an uncontrolled resource consumption vulnerability. Parsing decimal strings with exceptionally large exponents succeeds with minimal memory overhead, but subsequent arithmetic operations or string formatting attempts to materialize the expanded value. This exhausts BEAM Virtual Machine memory, causing an immediate denial of service.
The Elixir library ericmj/decimal provides arbitrary-precision decimal arithmetic for BEAM applications. Versions prior to 3.0.0 contain a critical uncontrolled resource consumption vulnerability classified under CWE-400. Unauthenticated remote attackers exploit this flaw to cause a persistent denial of service (DoS) by triggering an out-of-memory (OOM) condition in the underlying Erlang virtual machine.
The vulnerability originates from the library's design regarding exponent boundary enforcement. The software successfully parses and stores astronomical scientific notation strings in a compact struct format. However, it fails to impose maximum bounds on the exponent value during the initial parsing phase.
Applications become vulnerable when they accept these unbounded decimal values from external inputs, such as JSON payloads or API parameters, and process them further. When the application executes arithmetic operations or type conversions on the malicious decimal, the library attempts to materialize the expanded value in memory. This instantly consumes all available RAM and terminates the BEAM node.
The decimal library represents numbers using a standard struct: %Decimal{sign: sign, coef: coef, exp: exp}. Storing a value like Decimal.new("1e1000000000") populates the struct with a coefficient of 1 and an exponent of 1,000,000,000. This immediate parsing step operates in constant time and consumes negligible memory footprint.
The exploitation sink exists in the functions responsible for arithmetic alignment and materialization. When an application calls functions such as Decimal.add/2 or Decimal.sub/2, the library must align the decimal points of both operands. If one operand possesses a massive exponent, the execution path attempts to calculate 10^exponent to normalize the values.
Erlang natively supports arbitrary-precision integers (bignums), which allows this exponentiation attempt to proceed rather than throwing a standard integer overflow exception. The BEAM VM allocates memory proportional to the size of the resulting integer. An exponent of one billion requires gigabytes of memory to represent, leading to immediate system resource exhaustion.
String formatting and type conversion functions introduce secondary attack vectors. Calling Decimal.to_string/2 with :normal or :xsd formats instructs the library to expand the scientific notation into a literal string representation. Similarly, Decimal.to_integer/1 attempts to materialize the full numeric value, triggering the exact same bignum allocation failure.
Prior to version 3.0.0, the Decimal.Context configuration defaulted the emax (maximum exponent) attribute to :infinity. The parsing logic in lib/decimal.ex trusted the incoming scientific notation and directly mapped the parsed integer to the struct's exp field without bounds checking.
Commit 6a523f3a73b8c9974540e21c7aa88f1258bb35ae resolves this by introducing mandatory, safe defaults aligned with the IEEE 754 decimal128 standard. The patch modifies the core configuration defaults and inserts strict validation gates into the parsing and casting functions.
# Vulnerable Context Default (Pre-patch)
defmodule Decimal.Context do
defstruct precision: 28, rounding: :half_up, flags: [], traps: [:invalid_operation, :division_by_zero], emax: :infinity, emin: :infinity
end
# Patched Context Default (Post-patch)
defmodule Decimal.Context do
# ...
# emax changed to 6_144 matching IEEE 754 decimal128
defstruct precision: 28, rounding: :half_up, flags: [], traps: [:invalid_operation, :division_by_zero], emax: 6_144, emin: -6_143
endThe fix establishes hardcoded limits: @default_max_digits is set to 34, and @default_max_exponent is set to 6,144. The parse/1, parse/2, cast/1, and cast/2 functions now validate inputs against these thresholds by default. Any input exceeding an absolute exponent of 6,144 is explicitly rejected during the parse phase, preventing the malicious struct from ever entering the application state.
Furthermore, the patch hardens the to_string/2 function by introducing @default_to_string_max_digits (6,178). If a formatting operation attempts to generate a string exceeding this character limit, the library safely raises an ArgumentError instead of allocating the massive binary string.
Exploitation requires no authentication and relies solely on the application accepting numeric or string-based decimal parameters. An attacker identifies an API endpoint, web form, or data ingestion pipeline that parses financial data, metrics, or any user-controlled decimal value.
The attacker submits a payload containing an extremely large scientific notation string, such as {"amount": "1e1000000000"}. The application parses this payload seamlessly, bypassing initial data format validations because the input is a structurally valid scientific representation.
The attack completes when the application logic performs a standard operation on the parsed decimal. The specific proof-of-concept requires only two steps: parsing the malicious input and interacting with it.
# 1. Parsing succeeds and consumes ~0 RAM
poison = Decimal.new("1e1000000000")
# 2. Arithmetic operation triggers the OOM crash
Decimal.add(poison, Decimal.new("1"))This behavior makes the exploit highly reliable and completely platform-agnostic, provided the underlying application utilizes the affected ericmj/decimal routines.
The exploitation of CVE-2026-32686 results in a total loss of application availability. Because Elixir and Erlang run within the BEAM VM, resource exhaustion at the process level cascades to the entire node. The OOM condition forces the VM to terminate abruptly, dropping all concurrent connections and halting all background processing.
In microservice architectures, this vulnerability enables cascading failures. An attacker can repeatedly submit the malicious payload to a load-balanced cluster, systematically terminating individual nodes as traffic routes to them. The lightweight nature of the payload means attackers can sustain the DoS condition with minimal bandwidth.
The CVSS v4.0 base score of 6.9 designates this as a MEDIUM severity issue, primarily due to a classification of the Attack Vector as Local (AV:L) in some advisories. However, in typical web application deployments, this vulnerability functions as a remote exploit over the network. The High Availability (VA:H) impact accurately reflects the severity of the node termination.
The primary remediation strategy requires updating the decimal dependency to version 3.0.0 or later. This version enforces strict limits on digit counts and exponent sizes by default, fully mitigating the risk of massive bignum allocations.
Developers must verify that their application code does not manually override the new default context. Setting Decimal.Context.set(%Decimal.Context{emax: :infinity}) reverts the library to its vulnerable state, bypassing the protections introduced in the patch.
If immediate dependency updates are restricted, security teams should implement input validation controls. Applications can utilize regex-based validation rules or Web Application Firewall (WAF) signatures to inspect and block incoming decimal strings containing exponent indicators (e or E) followed by values exceeding 6,000.
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| Product | Affected Versions | Fixed Version |
|---|---|---|
decimal ericmj | >= 0.1.0, < 3.0.0 | 3.0.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400: Uncontrolled Resource Consumption |
| Attack Vector | Network (via crafted scientific notation payload) |
| CVSS v4.0 | 6.9 (MEDIUM) |
| EPSS Score | 0.07% |
| Impact | High Availability (Denial of Service via OOM) |
| Exploit Status | Proof of Concept available |
| Patched Version | 3.0.0 |
The software does not properly control the allocation and maintenance of a limited resource thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.