CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-32686
6.90.07%

CVE-2026-32686: Unbounded Exponent Resource Exhaustion in ericmj/decimal

Amit Schendel
Amit Schendel
Senior Security Researcher

May 12, 2026·6 min read·5 visits

PoC Available

Executive Summary (TL;DR)

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.

Vulnerability Overview

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.

Root Cause Analysis

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.

Code Analysis

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
end

The 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 Methodology

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.

Impact Assessment

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.

Remediation and Mitigation

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.

Official Patches

GitHub AdvisoryOfficial Security Advisory for CVE-2026-32686

Fix Analysis (1)

Technical Appendix

CVSS Score
6.9/ 10
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
EPSS Probability
0.07%
Top 78% most exploited

Affected Systems

Elixir applications utilizing the ericmj/decimal packageErlang BEAM Virtual Machine environments processing untrusted decimal inputs

Affected Versions Detail

Product
Affected Versions
Fixed Version
decimal
ericmj
>= 0.1.0, < 3.0.03.0.0
AttributeDetail
CWE IDCWE-400: Uncontrolled Resource Consumption
Attack VectorNetwork (via crafted scientific notation payload)
CVSS v4.06.9 (MEDIUM)
EPSS Score0.07%
ImpactHigh Availability (Denial of Service via OOM)
Exploit StatusProof of Concept available
Patched Version3.0.0

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-400
Uncontrolled Resource Consumption

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.

Vulnerability Timeline

Vulnerability disclosed and CVE assigned
2026-05-07
Official patch and version 3.0.0 released
2026-05-07
GitHub Advisory GHSA-rhv4-8758-jx7v published
2026-05-07
NVD entry created and analyzed
2026-05-08

References & Sources

  • [1]GHSA-rhv4-8758-jx7v
  • [2]EEF CNA Record
  • [3]Fix Commit 6a523f3a73b8c9974540e21c7aa88f1258bb35ae
  • [4]OSV Data

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.