CVE-2026-109821
Unbounded port parsing in URI.parse/1 enables CPU exhaustion denial of service in Elixir
Improper Validation of Specified Quantity in Input vulnerability in the Elixir standard library's URI module allows an attacker who supplies a URL to cause a denial of service through CPU exhaustion.
URI.parse/1 converts the port component with String.to_integer/1 in split_authority/1 (lib/elixir/lib/uri.ex) without bounding its length, so a port of up to 1,262,592 decimal digits produces a bignum of that size and a longer one raises SystemLimitError. Rendering the parsed URI back to text (URI.to_string/1, inspect/1, logging, error formatting) converts the bignum with :erlang.integer_to_binary/1, which is quadratic on Erlang/OTP 27, 28 and 29.0: a 400,000-digit port renders in about 2.6 seconds and a 1 MB port in about 18 seconds. Ports above 65535 are also accepted.
This issue affects elixir: from 0.5.0 before 1.18.6, from 1.19.0-rc.0 before 1.19.7, and from 1.20.0-rc.0 before 1.20.5.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
6.3
Unbounded port parsing in URI.parse/1 enables CPU exhaustion denial of service in Elixir
Improper Validation of Specified Quantity in Input vulnerability in the Elixir standard library's URI module allows an attacker who supplies a URL to cause a denial of service through CPU exhaustion.
URI.parse/1 converts the port component with String.to_integer/1 in split_authority/1 (lib/elixir/lib/uri.ex) without bounding its length, so a port of up to 1,262,592 decimal digits produces a bignum of that size and a longer one raises SystemLimitError. Rendering the parsed URI back to text (URI.to_string/1, inspect/1, logging, error formatting) converts the bignum with :erlang.integer_to_binary/1, which is quadratic on Erlang/OTP 27, 28 and 29.0: a 400,000-digit port renders in about 2.6 seconds and a 1 MB port in about 18 seconds. Ports above 65535 are also accepted.
This issue affects elixir: from 0.5.0 before 1.18.6, from 1.19.0-rc.0 before 1.19.7, and from 1.20.0-rc.0 before 1.20.5.
- Record
CVE-2026-109821- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-1284, CWE-400
- Updated
- 2026-11-02
EUVDEUVD-2026-113757
6.3
Improper Validation of Specified Quantity in Input vulnerability in the Elixir standard library's URI module allows an attacker who supplies a URL to cause a denial of service through CPU exhaustion.
URI.parse/1 converts the port component with String.to_integer/1 in split_authority/1 (lib/elixir/lib/uri.ex) without bounding its length, so a port of up to 1,262,592 decimal digits produces a bignum of that size and a longer one raises SystemLimitError. Rendering the parsed URI back to text (URI.to_string/1, inspect/1, logging, error formatting) converts the bignum with :erlang.integer_to_binary/1, which is quadratic on Erlang/OTP 27, 28 and 29.0: a 400,000-digit port renders in about 2.6 seconds and a 1 MB port in about 18 seconds. Ports above 65535 are also accepted.
This issue affects elixir: from 0.5.0 before 1.18.6, from 1.19.0-rc.0 before 1.19.7, and from 1.20.0-rc.0 before 1.20.5.
- Record
EUVD-2026-113757- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - Updated
- 2026-11-02
NVD
6.3
Improper Validation of Specified Quantity in Input vulnerability in the Elixir standard library's URI module allows an attacker who supplies a URL to cause a denial of service through CPU exhaustion.
URI.parse/1 converts the port component with String.to_integer/1 in split_authority/1 (lib/elixir/lib/uri.ex) without bounding its length, so a port of up to 1,262,592 decimal digits produces a bignum of that size and a longer one raises SystemLimitError. Rendering the parsed URI back to text (URI.to_string/1, inspect/1, logging, error formatting) converts the bignum with :erlang.integer_to_binary/1, which is quadratic on Erlang/OTP 27, 28 and 29.0: a 400,000-digit port renders in about 2.6 seconds and a 1 MB port in about 18 seconds. Ports above 65535 are also accepted.
This issue affects elixir: from 0.5.0 before 1.18.6, from 1.19.0-rc.0 before 1.19.7, and from 1.20.0-rc.0 before 1.20.5.
- Record
CVE-2026-109821- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/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 - Weakness
- CWE-400, CWE-1284
- Updated
- 2026-11-02
OSV
6.3
Unbounded port parsing in URI.parse/1 enables CPU exhaustion denial of service in Elixir
Improper Validation of Specified Quantity in Input vulnerability in the Elixir standard library's URI module allows an attacker who supplies a URL to cause a denial of service through CPU exhaustion.
URI.parse/1 converts the port component with String.to_integer/1 in split_authority/1 (lib/elixir/lib/uri.ex) without bounding its length, so a port of up to 1,262,592 decimal digits produces a bignum of that size and a longer one raises SystemLimitError. Rendering the parsed URI back to text (URI.to_string/1, inspect/1, logging, error formatting) converts the bignum with :erlang.integer_to_binary/1, which is quadratic on Erlang/OTP 27, 28 and 29.0: a 400,000-digit port renders in about 2.6 seconds and a 1 MB port in about 18 seconds. Ports above 65535 are also accepted.
This issue affects elixir: from 0.5.0 before 1.18.6, from 1.19.0-rc.0 before 1.19.7, and from 1.20.0-rc.0 before 1.20.5.
- Record
CVE-2026-109821- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-1284, CWE-400
- Updated
- 2026-11-03
OSVDEBIAN-CVE-2026-109821
6.3
Improper Validation of Specified Quantity in Input vulnerability in the Elixir standard library's URI module allows an attacker who supplies a URL to cause a denial of service through CPU exhaustion. URI.parse/1 converts the port component with String.to_integer/1 in split_authority/1 (lib/elixir/lib/uri.ex) without bounding its length, so a port of up to 1,262,592 decimal digits produces a bignum of that size and a longer one raises SystemLimitError. Rendering the parsed URI back to text (URI.to_string/1, inspect/1, logging, error formatting) converts the bignum with :erlang.integer_to_binary/1, which is quadratic on Erlang/OTP 27, 28 and 29.0: a 400,000-digit port renders in about 2.6 seconds and a 1 MB port in about 18 seconds. Ports above 65535 are also accepted. This issue affects elixir: from 0.5.0 before 1.18.6, from 1.19.0-rc.0 before 1.19.7, and from 1.20.0-rc.0 before 1.20.5.
- Record
DEBIAN-CVE-2026-109821- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/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 - Updated
- 2026-11-06
OSVEEF-CVE-2026-109821
6.3
Unbounded port parsing in URI.parse/1 enables CPU exhaustion denial of service in Elixir
Summary
Improper Validation of Specified Quantity in Input vulnerability in the Elixir standard library's URI module allows an attacker who supplies a URL to cause a denial of service through CPU exhaustion.
URI.parse/1 converts the port component with String.to_integer/1 in split_authority/1 (lib/elixir/lib/uri.ex) without bounding its length, so a port of up to 1,262,592 decimal digits produces a bignum of that size and a longer one raises SystemLimitError. Rendering the parsed URI back to text (URI.to_string/1, inspect/1, logging, error formatting) converts the bignum with :erlang.integer_to_binary/1, which is quadratic on Erlang/OTP 27, 28 and 29.0: a 400,000-digit port renders in about 2.6 seconds and a 1 MB port in about 18 seconds. Ports above 65535 are also accepted.
This issue affects elixir: from 0.5.0 before 1.18.6, from 1.19.0-rc.0 before 1.19.7, and from 1.20.0-rc.0 before 1.20.5.
Details
1. Unbounded conversion
split_authority/1 matches the port with the regex (:(\d*))? and converts it with String.to_integer/1. Nothing bounds the digit run, so the VM builds an integer of up to 1,262,592 decimal digits (about 30 ms to parse 400,000 digits) and raises SystemLimitError above that, which escapes URI.parse/1 instead of producing a %URI{}.
2. Render cost
URI.to_string/1 renders the port with Integer.to_string/1, and inspect/1 renders it the same way, both through :erlang.integer_to_binary/1. That conversion is quadratic on OTP 27, 28 and 29.0 and sub-quadratic from OTP 29.1 (https://github.com/erlang/otp/pull/11074). Per GHSA-8qw4-2chm-mvj2 it occupies a dirty CPU scheduler for its full duration.
3. Comparison with URI.new/1
Erlang/OTP limited the port to 5 bytes in :uri_string.parse/1 as part of GHSA-8qw4-2chm-mvj2. URI.new/1 and URI.new!/1 use :uri_string and get that limit on patched OTP versions. URI.parse/1 does its own parsing and does not.
4. Reach
Header-sourced URLs are bounded by HTTP server limits. Form and JSON body fields are not: Plug's default JSON body limit is 8 MB. One observed library path: a user-supplied URL passed to Req inside a Bandit request exits with the port in its arguments, and Bandit's error logging formats it, which took 2.8 seconds at 400,000 digits on OTP 28.
Proof of concept
- Build
url = "http://example.com:" <> String.duplicate("9", 400_000). URI.parse(url)returns in about 30 ms.URI.to_string(URI.parse(url))takes 2,613 ms on OTP 27.3.4.18, 2,604 ms on OTP 28.5 and 108 ms on OTP 29.1.1. With 200,000 digits it takes 654 ms on OTP 27 and 28, so the cost grows 4x per doubling.- The same digits placed in the path instead of the port parse and render in 1 ms or less.
URI.parse("http://example.com:65536").portreturns65536, and a port of 1,262,593 digits raisesSystemLimitError.
Impact
An unauthenticated client that submits a URL with a port of hundreds of thousands of digits makes the server build a bignum of that size, and each later rendering of the parsed URI costs seconds of CPU on Erlang/OTP 27, 28 and 29.0. Sustained requests exhaust CPU on applications that parse and log, store or echo user-supplied URLs.
Workarounds
Reject long URLs before parsing them, for example anything above a few kilobytes, and reject a parsed port above 65535 before rendering or using the %URI{}. URI.new/1 is not affected on Erlang/OTP 27.3.4.17, 28.5.0.6, 29.0.6 and later, where :uri_string limits the port to 5 digits.
Configurations
The application parses an attacker-supplied URL with URI.parse/1, for example a URL field in a form or JSON request body, and then renders the result or a value containing it. The multi-second render cost requires Erlang/OTP 27, 28 or 29.0; on OTP 29.1 and later rendering a 1 MB port takes under a second. URLs in HTTP headers and the request line are bounded by the server's size limits.
- Record
EEF-CVE-2026-109821- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - Weakness
- CWE-1284, CWE-400
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-109821
6.3
Improper Validation of Specified Quantity in Input vulnerability in the Elixir standard library's URI module allows an attacker who supplies a URL to cause a denial of service through CPU exhaustion. URI.parse/1 converts the port component with String.to_integer/1 in split_authority/1 (lib/elixir/lib/uri.ex) without bounding its length, so a port of up to 1,262,592 decimal digits produces a bignum of that size and a longer one raises SystemLimitError. Rendering the parsed URI back to text (URI.to_string/1, inspect/1, logging, error formatting) converts the bignum with :erlang.integer_to_binary/1, which is quadratic on Erlang/OTP 27, 28 and 29.0: a 400,000-digit port renders in about 2.6 seconds and a 1 MB port in about 18 seconds. Ports above 65535 are also accepted. This issue affects elixir: from 0.5.0 before 1.18.6, from 1.19.0-rc.0 before 1.19.7, and from 1.20.0-rc.0 before 1.20.5.
- Record
UBUNTU-CVE-2026-109821- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N - Updated
- 2026-11-05
OSVAZL-111661 No score
CVE-2026-109821 affecting package elixir 1.16.1-3
Improper Validation of Specified Quantity in Input vulnerability in the Elixir standard library's URI module allows an attacker who supplies a URL to cause a denial of service through CPU exhaustion.
URI.parse/1 converts the port component with String.to_integer/1 in split_authority/1 (lib/elixir/lib/uri.ex) without bounding its length, so a port of up to 1,262,592 decimal digits produces a bignum of that size and a longer one raises SystemLimitError. Rendering the parsed URI back to text (URI.to_string/1, inspect/1, logging, error formatting) converts the bignum with :erlang.integer_to_binary/1, which is quadratic on Erlang/OTP 27, 28 and 29.0: a 400,000-digit port renders in about 2.6 seconds and a 1 MB port in about 18 seconds. Ports above 65535 are also accepted.
This issue affects elixir: from 0.5.0 before 1.18.6, from 1.19.0-rc.0 before 1.19.7, and from 1.20.0-rc.0 before 1.20.5.
- Record
AZL-111661- Updated
- 2026-11-05
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
elixirAzure Linux:3 |
through 1.16.1-3 | None known |
elixir-langDebian:12 |
All versions, plus listed versions 1.14.0.dfsg-21.17.3.dfsg-11.17.3.dfsg-21.18.1.dfsg-11.18.1.dfsg-1.1 Show 8 moreShow less1.18.3.dfsg-11.18.3.dfsg-21.19.5.dfsg-11.19.5.dfsg-21.20.0.dfsg-11.20.1.dfsg-11.20.1.dfsg-21.20.4+dfsg-1 |
None known |
elixir-langDebian:13 |
All versions, plus listed versions 1.18.3.dfsg-11.18.3.dfsg-21.19.5.dfsg-11.19.5.dfsg-21.20.0.dfsg-11.20.1.dfsg-11.20.1.dfsg-21.20.4+dfsg-1 |
None known |
elixir-langDebian:14 |
All versions, plus listed versions 1.18.3.dfsg-11.18.3.dfsg-21.19.5.dfsg-11.19.5.dfsg-21.20.0.dfsg-11.20.1.dfsg-11.20.1.dfsg-21.20.4+dfsg-1 |
None known |
elixirUbuntu:14.04:LTS |
All versions, plus listed versions 0.7.1-10.7.1-20.7.1-4build0.14.04.1 |
None known |
elixirUbuntu:16.04:LTS |
All versions, plus listed versions 0.7.1-30.7.1-4build0.16.04.1 |
None known |
elixirUbuntu:18.04:LTS |
All versions, plus listed versions 0.7.1-4build1 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, aliases, references | OSV | |
| facts, published | OSV | |
| first indexed | CVE List, EUVD, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-109821 is a medium vulnerability (CVSS 6.3) in Elixir-lang Elixir, published October 30, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.50%, the 42nd percentile. No source names a fixed version.
References
github.com/elixir-lang/elixir/security/advisories/GHSA-327h-97cv-59xg
cna.erlef.org/cves/CVE-2026-109821.html
osv.dev/vulnerability/EEF-CVE-2026-109821
github.com/erlang/otp/security/advisories/GHSA-8qw4-2chm-mvj2
github.com/elixir-lang/elixir/commit/39801821eef2d06524e5ebf5a0e4b3c380ad23ae
github.com/elixir-lang/elixir/commit/9a39d64a4473d02681c486bc70681c972479d32b
Show 10 moreShow less
github.com/elixir-lang/elixir/commit/b70f33a591b6ab8eb0fa4a7e00bac1c2ed4e0d58
github.com/elixir-lang/elixir/commit/07d9abc3f3ac4c8d2ba8384bd102b6d6205b08b7
github.com/elixir-lang/elixir/commit/d879b39d778fec2f475689573d5672720c4f2a21
nvd.nist.gov/vuln/detail/CVE-2026-109821
github.com
github.com/CVEProject/cvelistV5/tree/main/cves/2026/109xxx/CVE-2026-109821.json
github.com/elixir-lang/elixir
security-tracker.debian.org/tracker/CVE-2026-109821
ubuntu.com/security/CVE-2026-109821
cve.org/CVERecord?id=CVE-2026-109821