CVE-2026-49762 Overview
CVE-2026-49762 is an uncontrolled resource consumption vulnerability [CWE-400] in the Elixir standard library's Version module. The version parser converts numeric components to integers without bounding their length. A single all-digit component around one megabyte forces a super-linear, non-yielding base-10 to arbitrary-precision conversion that pins a BEAM scheduler. A larger component raises an uncaught SystemLimitError that crashes the calling process. The flaw is reachable through Version.parse/1, Version.parse!/1, Version.match?/3, Version.compare/2, and Version.parse_requirement/1. Applications routinely pass untrusted HTTP parameters, dependency-manifest fields, and package metadata to these functions. The issue affects Elixir from 1.5.0 before 1.20.1.
Critical Impact
An unauthenticated attacker controlling a single version string can exhaust CPU and memory on a BEAM scheduler, causing denial of service in any Elixir application that parses untrusted version data.
Affected Products
- Elixir versions 1.5.0 through 1.20.0
- Applications calling Version.parse/1, Version.parse!/1, or Version.match?/3 on untrusted input
- Services parsing Version.compare/2 or Version.parse_requirement/1 against attacker-controlled strings
Discovery Timeline
- 2026-06-09 - CVE-2026-49762 published to NVD
- 2026-06-09 - Last updated in NVD database
Technical Details for CVE-2026-49762
Vulnerability Analysis
The Elixir Version module implements Semantic Versioning parsing in lib/version.ex. The parser splits a version string into major, minor, patch, and optional pre-release and build identifiers. For numeric components, it calls String.to_integer/1, which delegates to :erlang.binary_to_integer/1. This conversion is implemented as a tight, non-yielding BIF (Built-In Function) on the BEAM virtual machine. The conversion cost grows super-linearly with input length because Erlang integers are arbitrary precision.
An attacker who submits a version string containing a numeric component of roughly one megabyte forces the scheduler to spend seconds or minutes converting digits. The scheduler does not yield during this work, blocking other processes assigned to it. A larger component triggers an uncaught SystemLimitError, terminating the calling process and any work it owned.
Root Cause
The parser routine 'Elixir.Version.Parser':parse_digits/2 accepts digit runs of unbounded length. No length cap is applied before the digits are passed to integer conversion. Common application patterns expose the parser to untrusted data without sanitization.
Attack Vector
Exploitation requires only a single HTTP request, package manifest field, or API parameter containing a long all-digit version component such as 1.0.<one million digits>. No authentication is required. Any endpoint that calls Version.parse/1, Version.match?/3, or Version.parse_requirement/1 against caller-supplied input is reachable.
MAJOR.MINOR.PATCH
+ Each numeric component is limited to at most 14 digits.
+
Pre-releases are supported by optionally appending a hyphen and a series of
period-separated identifiers immediately following the patch version.
Identifiers consist of only ASCII alphanumeric characters and hyphens (`[0-9A-Za-z-]`):
"1.0.0-alpha.3"
+ Numeric pre-release identifiers are also limited to at most 14 digits.
+
Build information can be added by appending a plus sign and a series of
dot-separated identifiers immediately following the patch or pre-release version.
Identifiers consist of only ASCII alphanumeric characters and hyphens (`[0-9A-Za-z-]`):
Source: GitHub Elixir Commit c64417d — the patch caps each numeric component at 14 digits, preventing super-linear conversion cost.
Detection Methods for CVE-2026-49762
Indicators of Compromise
- HTTP requests, API calls, or manifest uploads containing version strings with numeric components longer than 14 digits
- BEAM scheduler utilization spikes correlated with Version.parse or Version.match? call stacks
- Crash reports referencing SystemLimitError originating from :erlang.binary_to_integer/1 or 'Elixir.Version.Parser':parse_digits/2
Detection Strategies
- Inspect application access logs for query parameters, headers, or JSON fields matching long digit sequences in version-shaped values
- Sample BEAM scheduler run-queue metrics and process reductions to flag unyielding work units against Version module functions
- Audit dependency-manifest ingestion paths and package-registry endpoints for unbounded version strings
Monitoring Recommendations
- Track process exits where the exit reason references SystemLimitError or binary_to_integer
- Alert on sustained per-scheduler CPU pinning combined with elevated request latency at endpoints accepting version input
- Forward Phoenix and Plug request logs to a central analytics system to baseline normal version-string lengths
How to Mitigate CVE-2026-49762
Immediate Actions Required
- Upgrade Elixir to version 1.20.1 or later across all build and runtime environments
- Validate and length-cap any user-controlled string before passing it to Version.parse/1, Version.match?/3, or Version.parse_requirement/1
- Inventory application code for calls into the Version module that accept external input, including dependency manifests and package metadata
Patch Information
The fix is delivered in Elixir 1.20.1. The upstream commit c64417d72fd5c7d09e963ca3ac5fa2b140978d9e limits each numeric component, including numeric pre-release identifiers, to at most 14 digits. See the GitHub Security Advisory GHSA-w2h8-8x3g-278p and the CNA CVE-2026-49762 Advisory for full details.
Workarounds
- Reject version strings longer than a small bound such as 256 bytes at the input boundary before any parsing occurs
- Wrap calls to Version functions in a guard that checks byte_size/1 and rejects oversized values with a 400 response
- Run version parsing inside a Task with a short timeout so a stalled conversion can be terminated without affecting the request scheduler
# Configuration example: pin Elixir to the patched release
asdf install elixir 1.20.1
asdf global elixir 1.20.1
# Validate input length before parsing in application code
# if byte_size(version_string) > 256, do: {:error, :too_long},
# else: Version.parse(version_string)
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

