Search
Find a vulnerability
Search criteria
81 vulnerabilities by Erlang
CVE-2026-96596 (GCVE-0-2026-96596)
Vulnerability from nvd – Published: 2026-10-14 16:56 – Updated: 2026-10-16 20:08
VLAI
EPSS
VEX
Title
erl_tar:extract/2 loops forever on a GNU sparse member with a trailing hole
Summary
Loop with Unreachable Exit Condition ('Infinite Loop') vulnerability in Erlang OTP stdlib (erl_tar module), hexpm hex_core (hex_erl_tar module), hexpm hex (mix_hex_erl_tar module) and erlang rebar3 (r3_hex_erl_tar module) allows an attacker who supplies a tar archive to cause a denial of service via a crafted GNU sparse member.
When erl_tar:extract/1,2 writes a member to disk, erl_tar:stream_to_file_loop/3 reads it in chunks of 65536 bytes by default. For a GNU sparse member whose sparse map ends before its real size, erl_tar:do_sparse_read/3 matches its trailing-hole clause before its zero-length clause. After the chunk is used up, the trailing-hole clause reads zero bytes, does not advance the position, and recurses forever. A 2048-byte archive keeps the extracting process and one scheduler busy until the process is killed. The {max_size, N} option prevents this only when N is below the real size of the member. Extraction with the memory option is not affected.
hex_core ships its own copy of erl_tar as hex_erl_tar, and Hex and rebar3 ship hex_core with prefixed module names (mix_hex_erl_tar and r3_hex_erl_tar). These copies contain the same code and do not call stdlib's erl_tar, so they are affected on any OTP version. OTP 28 is not affected, but an application running on OTP 28 is affected if it extracts archives through an affected version of hex_core, Hex or rebar3.
This issue affects OTP from OTP 29.0 before OTP 29.1.2, corresponding to stdlib from 8.0 before 8.1.1, and rebar3 from 3.27.1 onward, and hex from 2.4.2 before 2.5.3; hex_core: from 0.14.0 before 0.20.1.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-10-16 20:07 UTC
CWE
- CWE-835 - Loop with Unreachable Exit Condition ('Infinite Loop')
Assigner
References
12 references
Impacted products
9 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
29.0 , < 29.1.2
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
8.0 , < 8.1.1
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
fbf2c7194f6fce4b7b66dc0bcaa4f6b4b85e088f , < 3086307f311b78b38644a7787a3aca6a3f95a9d5
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| erlang | rebar3 |
Affected:
3.27.1 , < *
(semver)
cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:* |
|
| erlang | rebar3 |
Affected:
23dbdb5d1f87f56902aef296c88a20049cd0c6e4 , < *
(git)
cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:* |
|
| hexpm | hex_core |
Affected:
0.14.0 , < 0.20.1
(semver)
cpe:2.3:a:hexpm:hex_core:*:*:*:*:*:*:*:* |
|
| hexpm | hex_core |
Affected:
13bb9fbba418a406af614790b8d5cd458259ee70 , < a2ece683e6e88a3ec95ad20b09aca426e08b372e
(git)
cpe:2.3:a:hexpm:hex_core:*:*:*:*:*:*:*:* |
|
| hexpm | hex |
Affected:
2.4.2 , < 2.5.3
(semver)
cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:* |
|
| hexpm | hex |
Affected:
5543a1919c709d8eb2b317f62aad76ca1eed375c , < *
(git)
cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:* |
Date Public
2026-10-14 16:56
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-96596",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-10-16T20:07:46.754736Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-10-16T20:08:17.542Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"erl_tar"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/stdlib/src/erl_tar.erl"
],
"programRoutines": [
{
"name": "erl_tar:do_sparse_read/3"
},
{
"name": "erl_tar:stream_to_file_loop/3"
},
{
"name": "erl_tar:extract/1"
},
{
"name": "erl_tar:extract/2"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "29.1.2",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"erl_tar"
],
"packageName": "stdlib",
"packageURL": "pkg:otp/stdlib?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Fotp\u0026vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Ferlang%2Fotp.git",
"product": "OTP",
"programFiles": [
"src/erl_tar.erl"
],
"programRoutines": [
{
"name": "erl_tar:do_sparse_read/3"
},
{
"name": "erl_tar:stream_to_file_loop/3"
},
{
"name": "erl_tar:extract/1"
},
{
"name": "erl_tar:extract/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "8.1.1",
"status": "affected",
"version": "8.0",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"erl_tar"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/stdlib/src/erl_tar.erl"
],
"programRoutines": [
{
"name": "erl_tar:do_sparse_read/3"
},
{
"name": "erl_tar:stream_to_file_loop/3"
},
{
"name": "erl_tar:extract/1"
},
{
"name": "erl_tar:extract/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "3086307f311b78b38644a7787a3aca6a3f95a9d5",
"status": "affected",
"version": "fbf2c7194f6fce4b7b66dc0bcaa4f6b4b85e088f",
"versionType": "git"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"r3_hex_erl_tar",
"r3_hex_tarball"
],
"packageName": "rebar3",
"packageURL": "pkg:otp/rebar3?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Frebar3\u0026vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Ferlang%2Frebar3.git",
"product": "rebar3",
"programFiles": [
"apps/rebar/src/vendored/r3_hex_erl_tar.erl",
"apps/rebar/src/vendored/r3_hex_tarball.erl"
],
"programRoutines": [
{
"name": "r3_hex_erl_tar:do_sparse_read/3"
},
{
"name": "r3_hex_erl_tar:stream_to_file_loop/3"
},
{
"name": "r3_hex_erl_tar:extract/1"
},
{
"name": "r3_hex_erl_tar:extract/2"
},
{
"name": "r3_hex_tarball:unpack/2"
},
{
"name": "r3_hex_tarball:unpack/3"
},
{
"name": "r3_hex_tarball:unpack_docs/2"
},
{
"name": "r3_hex_tarball:unpack_docs/3"
}
],
"repo": "https://github.com/erlang/rebar3",
"vendor": "erlang",
"versions": [
{
"lessThan": "*",
"status": "affected",
"version": "3.27.1",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"r3_hex_erl_tar",
"r3_hex_tarball"
],
"packageName": "erlang/rebar3",
"packageURL": "pkg:github/erlang/rebar3",
"product": "rebar3",
"programFiles": [
"apps/rebar/src/vendored/r3_hex_erl_tar.erl",
"apps/rebar/src/vendored/r3_hex_tarball.erl"
],
"programRoutines": [
{
"name": "r3_hex_erl_tar:do_sparse_read/3"
},
{
"name": "r3_hex_erl_tar:stream_to_file_loop/3"
},
{
"name": "r3_hex_erl_tar:extract/1"
},
{
"name": "r3_hex_erl_tar:extract/2"
},
{
"name": "r3_hex_tarball:unpack/2"
},
{
"name": "r3_hex_tarball:unpack/3"
},
{
"name": "r3_hex_tarball:unpack_docs/2"
},
{
"name": "r3_hex_tarball:unpack_docs/3"
}
],
"repo": "https://github.com/erlang/rebar3",
"vendor": "erlang",
"versions": [
{
"lessThan": "*",
"status": "affected",
"version": "23dbdb5d1f87f56902aef296c88a20049cd0c6e4",
"versionType": "git"
}
]
},
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:hexpm:hex_core:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"hex_erl_tar",
"hex_tarball"
],
"packageName": "hex_core",
"packageURL": "pkg:hex/hex_core",
"product": "hex_core",
"programFiles": [
"src/hex_erl_tar.erl",
"src/hex_tarball.erl"
],
"programRoutines": [
{
"name": "hex_erl_tar:do_sparse_read/3"
},
{
"name": "hex_erl_tar:stream_to_file_loop/3"
},
{
"name": "hex_erl_tar:extract/1"
},
{
"name": "hex_erl_tar:extract/2"
},
{
"name": "hex_tarball:unpack/2"
},
{
"name": "hex_tarball:unpack/3"
},
{
"name": "hex_tarball:unpack_docs/2"
},
{
"name": "hex_tarball:unpack_docs/3"
}
],
"repo": "https://github.com/hexpm/hex_core",
"vendor": "hexpm",
"versions": [
{
"lessThan": "0.20.1",
"status": "affected",
"version": "0.14.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:hexpm:hex_core:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"hex_erl_tar",
"hex_tarball"
],
"packageName": "hexpm/hex_core",
"packageURL": "pkg:github/hexpm/hex_core",
"product": "hex_core",
"programFiles": [
"src/hex_erl_tar.erl",
"src/hex_tarball.erl"
],
"programRoutines": [
{
"name": "hex_erl_tar:do_sparse_read/3"
},
{
"name": "hex_erl_tar:stream_to_file_loop/3"
},
{
"name": "hex_erl_tar:extract/1"
},
{
"name": "hex_erl_tar:extract/2"
},
{
"name": "hex_tarball:unpack/2"
},
{
"name": "hex_tarball:unpack/3"
},
{
"name": "hex_tarball:unpack_docs/2"
},
{
"name": "hex_tarball:unpack_docs/3"
}
],
"repo": "https://github.com/hexpm/hex_core",
"vendor": "hexpm",
"versions": [
{
"lessThan": "a2ece683e6e88a3ec95ad20b09aca426e08b372e",
"status": "affected",
"version": "13bb9fbba418a406af614790b8d5cd458259ee70",
"versionType": "git"
}
]
},
{
"cpes": [
"cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"mix_hex_erl_tar",
"mix_hex_tarball"
],
"packageName": "hex",
"packageURL": "pkg:otp/hex?repository_url=https:%2F%2Fgithub.com%2Fhexpm%2Fhex\u0026vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fhexpm%2Fhex.git",
"product": "hex",
"programFiles": [
"src/mix_hex_erl_tar.erl",
"src/mix_hex_tarball.erl"
],
"programRoutines": [
{
"name": "mix_hex_erl_tar:do_sparse_read/3"
},
{
"name": "mix_hex_erl_tar:stream_to_file_loop/3"
},
{
"name": "mix_hex_erl_tar:extract/1"
},
{
"name": "mix_hex_erl_tar:extract/2"
},
{
"name": "mix_hex_tarball:unpack/2"
},
{
"name": "mix_hex_tarball:unpack/3"
},
{
"name": "mix_hex_tarball:unpack_docs/2"
},
{
"name": "mix_hex_tarball:unpack_docs/3"
}
],
"repo": "https://github.com/hexpm/hex",
"vendor": "hexpm",
"versions": [
{
"lessThan": "2.5.3",
"status": "affected",
"version": "2.4.2",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"mix_hex_erl_tar",
"mix_hex_tarball"
],
"packageName": "hexpm/hex",
"packageURL": "pkg:github/hexpm/hex",
"product": "hex",
"programFiles": [
"src/mix_hex_erl_tar.erl",
"src/mix_hex_tarball.erl"
],
"programRoutines": [
{
"name": "mix_hex_erl_tar:do_sparse_read/3"
},
{
"name": "mix_hex_erl_tar:stream_to_file_loop/3"
},
{
"name": "mix_hex_erl_tar:extract/1"
},
{
"name": "mix_hex_erl_tar:extract/2"
},
{
"name": "mix_hex_tarball:unpack/2"
},
{
"name": "mix_hex_tarball:unpack/3"
},
{
"name": "mix_hex_tarball:unpack_docs/2"
},
{
"name": "mix_hex_tarball:unpack_docs/3"
}
],
"repo": "https://github.com/hexpm/hex",
"vendor": "hexpm",
"versions": [
{
"changes": [
{
"at": "8e1067131a13949eff30623f31648a945ffd5418",
"status": "unaffected"
},
{
"at": "7847c23d09ab52113614c3718e1e7d368743da5d",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "5543a1919c709d8eb2b317f62aad76ca1eed375c",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.1.2",
"versionStartIncluding": "29.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:*",
"versionStartIncluding": "3.27.1",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:hexpm:hex_core:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.20.1",
"versionStartIncluding": "0.14.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*",
"versionEndExcluding": "2.5.3",
"versionStartIncluding": "2.4.2",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Eric Meadows-J\u00f6nsson"
},
{
"lang": "en",
"type": "reporter",
"value": "Eric Meadows-J\u00f6nsson"
}
],
"dateAssigned": "2026-10-07T13:11:38.000Z",
"datePublic": "2026-10-14T16:56:18.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eLoop with Unreachable Exit Condition (\u0027Infinite Loop\u0027) vulnerability in Erlang OTP stdlib (\u003ccode\u003eerl_tar\u003c/code\u003e module), hexpm hex_core (\u003ccode\u003ehex_erl_tar\u003c/code\u003e module), hexpm hex (\u003ccode\u003emix_hex_erl_tar\u003c/code\u003e module) and erlang rebar3 (\u003ccode\u003er3_hex_erl_tar\u003c/code\u003e module) allows an attacker who supplies a tar archive to cause a denial of service via a crafted GNU sparse member.\u003c/p\u003e\n\u003cp\u003eWhen \u003ccode\u003eerl_tar:extract/1,2\u003c/code\u003e writes a member to disk, \u003ccode\u003eerl_tar:stream_to_file_loop/3\u003c/code\u003e reads it in chunks of 65536 bytes by default. For a GNU sparse member whose sparse map ends before its real size, \u003ccode\u003eerl_tar:do_sparse_read/3\u003c/code\u003e matches its trailing-hole clause before its zero-length clause. After the chunk is used up, the trailing-hole clause reads zero bytes, does not advance the position, and recurses forever. A 2048-byte archive keeps the extracting process and one scheduler busy until the process is killed. The \u003ccode\u003e{max_size, N}\u003c/code\u003e option prevents this only when N is below the real size of the member. Extraction with the \u003ccode\u003ememory\u003c/code\u003e option is not affected.\u003c/p\u003e\n\u003cp\u003ehex_core ships its own copy of \u003ccode\u003eerl_tar\u003c/code\u003e as \u003ccode\u003ehex_erl_tar\u003c/code\u003e, and Hex and rebar3 ship hex_core with prefixed module names (\u003ccode\u003emix_hex_erl_tar\u003c/code\u003e and \u003ccode\u003er3_hex_erl_tar\u003c/code\u003e). These copies contain the same code and do not call stdlib\u0027s \u003ccode\u003eerl_tar\u003c/code\u003e, so they are affected on any OTP version. OTP 28 is not affected, but an application running on OTP 28 is affected if it extracts archives through an affected version of hex_core, Hex or rebar3.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.1.2, corresponding to stdlib from 8.0 before 8.1.1, and rebar3 from 3.27.1 onward, and hex from 2.4.2 before 2.5.3; hex_core: from 0.14.0 before 0.20.1.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Loop with Unreachable Exit Condition (\u0027Infinite Loop\u0027) vulnerability in Erlang OTP stdlib (`erl_tar` module), hexpm hex_core (`hex_erl_tar` module), hexpm hex (`mix_hex_erl_tar` module) and erlang rebar3 (`r3_hex_erl_tar` module) allows an attacker who supplies a tar archive to cause a denial of service via a crafted GNU sparse member.\n\nWhen `erl_tar:extract/1,2` writes a member to disk, `erl_tar:stream_to_file_loop/3` reads it in chunks of 65536 bytes by default. For a GNU sparse member whose sparse map ends before its real size, `erl_tar:do_sparse_read/3` matches its trailing-hole clause before its zero-length clause. After the chunk is used up, the trailing-hole clause reads zero bytes, does not advance the position, and recurses forever. A 2048-byte archive keeps the extracting process and one scheduler busy until the process is killed. The `{max_size, N}` option prevents this only when N is below the real size of the member. Extraction with the `memory` option is not affected.\n\nhex_core ships its own copy of `erl_tar` as `hex_erl_tar`, and Hex and rebar3 ship hex_core with prefixed module names (`mix_hex_erl_tar` and `r3_hex_erl_tar`). These copies contain the same code and do not call stdlib\u0027s `erl_tar`, so they are affected on any OTP version. OTP 28 is not affected, but an application running on OTP 28 is affected if it extracts archives through an affected version of hex_core, Hex or rebar3.\n\nThis issue affects OTP from OTP\u00a029.0 before OTP\u00a029.1.2, corresponding to stdlib from 8.0 before 8.1.1, and rebar3 from 3.27.1 onward, and hex from 2.4.2 before 2.5.3; hex_core: from 0.14.0 before 0.20.1."
}
],
"value": "Loop with Unreachable Exit Condition (\u0027Infinite Loop\u0027) vulnerability in Erlang OTP stdlib (erl_tar module), hexpm hex_core (hex_erl_tar module), hexpm hex (mix_hex_erl_tar module) and erlang rebar3 (r3_hex_erl_tar module) allows an attacker who supplies a tar archive to cause a denial of service via a crafted GNU sparse member.\n\nWhen erl_tar:extract/1,2 writes a member to disk, erl_tar:stream_to_file_loop/3 reads it in chunks of 65536 bytes by default. For a GNU sparse member whose sparse map ends before its real size, erl_tar:do_sparse_read/3 matches its trailing-hole clause before its zero-length clause. After the chunk is used up, the trailing-hole clause reads zero bytes, does not advance the position, and recurses forever. A 2048-byte archive keeps the extracting process and one scheduler busy until the process is killed. The {max_size, N} option prevents this only when N is below the real size of the member. Extraction with the memory option is not affected.\n\nhex_core ships its own copy of erl_tar as hex_erl_tar, and Hex and rebar3 ship hex_core with prefixed module names (mix_hex_erl_tar and r3_hex_erl_tar). These copies contain the same code and do not call stdlib\u0027s erl_tar, so they are affected on any OTP version. OTP 28 is not affected, but an application running on OTP 28 is affected if it extracts archives through an affected version of hex_core, Hex or rebar3.\n\nThis issue affects OTP from OTP\u00a029.0 before OTP\u00a029.1.2, corresponding to stdlib from 8.0 before 8.1.1, and rebar3 from 3.27.1 onward, and hex from 2.4.2 before 2.5.3; hex_core: from 0.14.0 before 0.20.1."
}
],
"impacts": [
{
"capecId": "CAPEC-130",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAn attacker who can get an application to extract a tar archive to disk keeps the extracting process and one scheduler busy forever. Each further archive occupies another scheduler, until the node stops responding.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "An attacker who can get an application to extract a tar archive to disk keeps the extracting process and one scheduler busy forever. Each further archive occupies another scheduler, until the node stops responding."
}
],
"value": "An attacker who can get an application to extract a tar archive to disk keeps the extracting process and one scheduler busy forever. Each further archive occupies another scheduler, until the node stops responding."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "LOCAL",
"baseScore": 5.9,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-835",
"description": "CWE-835 Loop with Unreachable Exit Condition (\u0027Infinite Loop\u0027)",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-10-14T21:46:30.112Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-phm5-m6cj-5382"
},
{
"name": "EEF CNA record for CVE-2026-96596",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-96596.html"
},
{
"name": "OSV record EEF-CVE-2026-96596",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-96596"
},
{
"name": "Erlang/OTP version ordering",
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"name": "Introducing commit fbf2c71 in erlang/otp",
"tags": [
"related"
],
"url": "https://github.com/erlang/otp/commit/fbf2c7194f6fce4b7b66dc0bcaa4f6b4b85e088f"
},
{
"name": "Fix commit 3086307 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/3086307f311b78b38644a7787a3aca6a3f95a9d5"
},
{
"name": "Introducing commit 23dbdb5 in erlang/rebar3",
"tags": [
"related"
],
"url": "https://github.com/erlang/rebar3/commit/23dbdb5d1f87f56902aef296c88a20049cd0c6e4"
},
{
"name": "Introducing commit 13bb9fb in hexpm/hex_core",
"tags": [
"related"
],
"url": "https://github.com/hexpm/hex_core/commit/13bb9fbba418a406af614790b8d5cd458259ee70"
},
{
"name": "Fix commit a2ece68 in hexpm/hex_core",
"tags": [
"patch"
],
"url": "https://github.com/hexpm/hex_core/commit/a2ece683e6e88a3ec95ad20b09aca426e08b372e"
},
{
"name": "Introducing commit 5543a19 in hexpm/hex",
"tags": [
"related"
],
"url": "https://github.com/hexpm/hex/commit/5543a1919c709d8eb2b317f62aad76ca1eed375c"
},
{
"name": "Fix commit 8e10671 in hexpm/hex",
"tags": [
"patch"
],
"url": "https://github.com/hexpm/hex/commit/8e1067131a13949eff30623f31648a945ffd5418"
},
{
"name": "Fix commit 7847c23 in hexpm/hex",
"tags": [
"patch"
],
"url": "https://github.com/hexpm/hex/commit/7847c23d09ab52113614c3718e1e7d368743da5d"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "erl_tar:extract/2 loops forever on a GNU sparse member with a trailing hole",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003ePass \u003ccode\u003e{chunks, N}\u003c/code\u003e together with \u003ccode\u003e{max_size, N}\u003c/code\u003e, with the same value N, to \u003ccode\u003eerl_tar:extract/2\u003c/code\u003e. Extraction then rejects any member larger than N, and reads each remaining member in one call, so the loop cannot occur.\u003c/p\u003e\n\u003cp\u003eAlternatively, extract with the \u003ccode\u003ememory\u003c/code\u003e option and write the returned files to disk in the application.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Pass `{chunks, N}` together with `{max_size, N}`, with the same value N, to `erl_tar:extract/2`. Extraction then rejects any member larger than N, and reads each remaining member in one call, so the loop cannot occur.\n\nAlternatively, extract with the `memory` option and write the returned files to disk in the application."
}
],
"value": "Pass {chunks, N} together with {max_size, N}, with the same value N, to erl_tar:extract/2. Extraction then rejects any member larger than N, and reads each remaining member in one call, so the loop cannot occur.\n\nAlternatively, extract with the memory option and write the returned files to disk in the application."
}
],
"x_proofOfConcept": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003col\u003e\n\u003cli\u003eBuild a 2048-byte tar that holds one GNU sparse member (typeflag \u003ccode\u003eS\u003c/code\u003e). Give it a stored size of 4 bytes, one sparse map entry of 4 bytes at offset 0, and a real size of 1048576 bytes. Follow the 512-byte header with a 512-byte block that starts with the 4 data bytes, then 1024 zero bytes.\u003c/li\u003e\n\u003cli\u003eIn a separate process, call \u003ccode\u003eerl_tar:extract({binary, Tar}, [{cwd, Dir}])\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eThe call does not return. After 5 seconds the process has used more than 10^9 reductions. On OTP 28 the same call returns \u003ccode\u003eok\u003c/code\u003e.\u003c/li\u003e\n\u003c/ol\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "1. Build a 2048-byte tar that holds one GNU sparse member (typeflag `S`). Give it a stored size of 4 bytes, one sparse map entry of 4 bytes at offset 0, and a real size of 1048576 bytes. Follow the 512-byte header with a 512-byte block that starts with the 4 data bytes, then 1024 zero bytes.\n2. In a separate process, call `erl_tar:extract({binary, Tar}, [{cwd, Dir}])`.\n3. The call does not return. After 5 seconds the process has used more than 10^9 reductions. On OTP 28 the same call returns `ok`."
}
],
"value": "* Build a 2048-byte tar that holds one GNU sparse member (typeflag S). Give it a stored size of 4 bytes, one sparse map entry of 4 bytes at offset 0, and a real size of 1048576 bytes. Follow the 512-byte header with a 512-byte block that starts with the 4 data bytes, then 1024 zero bytes.\n* In a separate process, call erl_tar:extract({binary, Tar}, [{cwd, Dir}]).\n* The call does not return. After 5 seconds the process has used more than 10^9 reductions. On OTP 28 the same call returns ok."
}
],
"x_technicalAnalysis": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003e\u003cstrong\u003e1. Chunked extraction.\u003c/strong\u003e \u003ccode\u003eerl_tar:extract/2\u003c/code\u003e writes each member to disk through \u003ccode\u003estream_to_file_loop/3\u003c/code\u003e. This function calls \u003ccode\u003edo_read(Reader, ChunkSize)\u003c/code\u003e until the \u003ccode\u003enum_bytes\u003c/code\u003e field of the reader is 0. The default chunk size is 65536 bytes.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e2. Clause order in \u003ccode\u003edo_sparse_read/3\u003c/code\u003e.\u003c/strong\u003e For a sparse member, \u003ccode\u003edo_read/2\u003c/code\u003e calls \u003ccode\u003edo_sparse_read/3\u003c/code\u003e. The clause for a trailing hole matches when \u003ccode\u003esparse_map\u003c/code\u003e is \u003ccode\u003e[]\u003c/code\u003e and \u003ccode\u003ePos \u0026lt; Size\u003c/code\u003e. It comes before the clause that returns when \u003ccode\u003eLen\u003c/code\u003e is 0.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e3. Unbounded recursion.\u003c/strong\u003e The member is a GNU sparse member (typeflag \u003ccode\u003eS\u003c/code\u003e) whose real size is larger than one chunk and whose sparse map ends before the real size. After the data fragments, the trailing-hole clause reads the rest of the chunk and recurses with \u003ccode\u003eLen = 0\u003c/code\u003e. The same clause matches again, and \u003ccode\u003eread_sparse_hole/3\u003c/code\u003e returns an empty binary and leaves \u003ccode\u003ePos\u003c/code\u003e unchanged. The zero-length clause is never reached, so the call never returns.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e4. No mitigation from \u003ccode\u003emax_size\u003c/code\u003e.\u003c/strong\u003e For a sparse member, \u003ccode\u003e{max_size, N}\u003c/code\u003e is checked against the real size from the header. It stops the loop only when N is below that size. \u003ccode\u003eerl_tar:table/2\u003c/code\u003e lists the member as \u003ccode\u003eregular\u003c/code\u003e, so a caller cannot skip sparse members by type.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "**1. Chunked extraction.** `erl_tar:extract/2` writes each member to disk through `stream_to_file_loop/3`. This function calls `do_read(Reader, ChunkSize)` until the `num_bytes` field of the reader is 0. The default chunk size is 65536 bytes.\n\n**2. Clause order in `do_sparse_read/3`.** For a sparse member, `do_read/2` calls `do_sparse_read/3`. The clause for a trailing hole matches when `sparse_map` is `[]` and `Pos \u003c Size`. It comes before the clause that returns when `Len` is 0.\n\n**3. Unbounded recursion.** The member is a GNU sparse member (typeflag `S`) whose real size is larger than one chunk and whose sparse map ends before the real size. After the data fragments, the trailing-hole clause reads the rest of the chunk and recurses with `Len = 0`. The same clause matches again, and `read_sparse_hole/3` returns an empty binary and leaves `Pos` unchanged. The zero-length clause is never reached, so the call never returns.\n\n**4. No mitigation from `max_size`.** For a sparse member, `{max_size, N}` is checked against the real size from the header. It stops the loop only when N is below that size. `erl_tar:table/2` lists the member as `regular`, so a caller cannot skip sparse members by type."
}
],
"value": "1. Chunked extraction. erl_tar:extract/2 writes each member to disk through stream_to_file_loop/3. This function calls do_read(Reader, ChunkSize) until the num_bytes field of the reader is 0. The default chunk size is 65536 bytes.\n\n2. Clause order in do_sparse_read/3. For a sparse member, do_read/2 calls do_sparse_read/3. The clause for a trailing hole matches when sparse_map is [] and Pos \u003c Size. It comes before the clause that returns when Len is 0.\n\n3. Unbounded recursion. The member is a GNU sparse member (typeflag S) whose real size is larger than one chunk and whose sparse map ends before the real size. After the data fragments, the trailing-hole clause reads the rest of the chunk and recurses with Len = 0. The same clause matches again, and read_sparse_hole/3 returns an empty binary and leaves Pos unchanged. The zero-length clause is never reached, so the call never returns.\n\n4. No mitigation from max_size. For a sparse member, {max_size, N} is checked against the real size from the header. It stops the loop only when N is below that size. erl_tar:table/2 lists the member as regular, so a caller cannot skip sparse members by type."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-96596",
"datePublished": "2026-10-14T16:56:18.530Z",
"dateReserved": "2026-09-27T12:00:01.540Z",
"dateUpdated": "2026-10-16T20:08:17.542Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-94200 (GCVE-0-2026-94200)
Vulnerability from nvd – Published: 2026-10-14 16:55 – Updated: 2026-10-16 20:09
VLAI
EPSS
VEX
Title
TLS 1.3 client ticket store crashed by NewSessionTicket with empty early_data extension in ssl
Summary
Improper Validation of Consistency within Input vulnerability in Erlang OTP ssl (tls_handshake_1_3, ssl_handshake and tls_client_ticket_store modules) allows a malicious TLS 1.3 server to cause a denial of service of the ssl application on the client node.
The TLS 1.3 client decodes the extensions of a NewSessionTicket message as if they came from EncryptedExtensions. It therefore accepts a 0-length early_data extension, a form that is only valid in ClientHello and EncryptedExtensions. With {session_tickets, auto}, the client stores the ticket in the node-global tls_client_ticket_store. On the next automatic resumption, tls_handshake_1_3:get_max_early_data/1 crashes the store with a case_clause. Repeated crashes can exceed the restart intensity of the ssl supervisors, which use the rest_for_one strategy, and take down ssl for all connections on the node.
This issue affects OTP from OTP 23.3 before OTP 27.3.4.19, OTP 28.5.0.8, and OTP 29.1.2, corresponding to ssl from 10.3 before 11.2.12.14, 11.6.0.7, and 11.7.8.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-10-16 20:08 UTC
CWE
- CWE-1288 - Improper Validation of Consistency within Input
Assigner
References
8 references
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
23.3 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
10.3 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
0abe6f66db0d295cd06b0efab3bdb3caa2803930 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-94200",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-10-16T20:08:52.033542Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-10-16T20:09:04.559Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"ssl_handshake",
"tls_handshake_1_3",
"tls_client_ticket_store"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/ssl/src/ssl_handshake.erl",
"lib/ssl/src/tls_handshake_1_3.erl",
"lib/ssl/src/tls_client_ticket_store.erl"
],
"programRoutines": [
{
"name": "ssl_handshake:decode_extensions/4"
},
{
"name": "tls_handshake_1_3:decode_handshake/2"
},
{
"name": "tls_handshake_1_3:get_max_early_data/1"
},
{
"name": "tls_client_ticket_store:find_ticket/5"
},
{
"name": "tls_client_ticket_store:get_tickets/2"
}
],
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "27.3.4.19",
"status": "unaffected"
},
{
"at": "28.5.0.8",
"status": "unaffected"
},
{
"at": "29.1.2",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "23.3",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"ssl_handshake",
"tls_handshake_1_3",
"tls_client_ticket_store"
],
"packageName": "ssl",
"packageURL": "pkg:otp/ssl?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Fotp\u0026vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Ferlang%2Fotp.git",
"product": "OTP",
"programFiles": [
"src/ssl_handshake.erl",
"src/tls_handshake_1_3.erl",
"src/tls_client_ticket_store.erl"
],
"programRoutines": [
{
"name": "ssl_handshake:decode_extensions/4"
},
{
"name": "tls_handshake_1_3:decode_handshake/2"
},
{
"name": "tls_handshake_1_3:get_max_early_data/1"
},
{
"name": "tls_client_ticket_store:find_ticket/5"
},
{
"name": "tls_client_ticket_store:get_tickets/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "11.2.12.14",
"status": "unaffected"
},
{
"at": "11.6.0.7",
"status": "unaffected"
},
{
"at": "11.7.8",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "10.3",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"ssl_handshake",
"tls_handshake_1_3",
"tls_client_ticket_store"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/ssl/src/ssl_handshake.erl",
"lib/ssl/src/tls_handshake_1_3.erl",
"lib/ssl/src/tls_client_ticket_store.erl"
],
"programRoutines": [
{
"name": "ssl_handshake:decode_extensions/4"
},
{
"name": "tls_handshake_1_3:decode_handshake/2"
},
{
"name": "tls_handshake_1_3:get_max_early_data/1"
},
{
"name": "tls_client_ticket_store:find_ticket/5"
},
{
"name": "tls_client_ticket_store:get_tickets/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "66febc190e6dc42a5c4aedbfe250bf9a2edc2d5e",
"status": "unaffected"
},
{
"at": "00a333bcf2800b69f540369b54167e897dae7219",
"status": "unaffected"
},
{
"at": "cd0334854bf3ef56dc16f9fb728efe88fb05c4ac",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "0abe6f66db0d295cd06b0efab3bdb3caa2803930",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eOnly TLS 1.3 clients that set the \u003ccode\u003essl\u003c/code\u003e option \u003ccode\u003e{session_tickets, auto}\u003c/code\u003e are affected. The default value of \u003ccode\u003esession_tickets\u003c/code\u003e is \u003ccode\u003edisabled\u003c/code\u003e, and clients that use \u003ccode\u003emanual\u003c/code\u003e ticket handling do not store tickets in the node-global ticket store. The client must also connect to a server that the attacker controls, or that the attacker can impersonate.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Only TLS 1.3 clients that set the `ssl` option `{session_tickets, auto}` are affected. The default value of `session_tickets` is `disabled`, and clients that use `manual` ticket handling do not store tickets in the node-global ticket store. The client must also connect to a server that the attacker controls, or that the attacker can impersonate."
}
],
"value": "Only TLS 1.3 clients that set the ssl option {session_tickets, auto} are affected. The default value of session_tickets is disabled, and clients that use manual ticket handling do not store tickets in the node-global ticket store. The client must also connect to a server that the attacker controls, or that the attacker can impersonate."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.19",
"versionStartIncluding": "23.3",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.8",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.1.2",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Lukas Backstr\u00f6m / Erlang Solutions"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Ingela Anderton Andin"
},
{
"lang": "en",
"type": "coordinator",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-10-01T08:50:00.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Validation of Consistency within Input vulnerability in Erlang OTP ssl (\u003ccode\u003etls_handshake_1_3\u003c/code\u003e, \u003ccode\u003essl_handshake\u003c/code\u003e and \u003ccode\u003etls_client_ticket_store\u003c/code\u003e modules) allows a malicious TLS 1.3 server to cause a denial of service of the \u003ccode\u003essl\u003c/code\u003e application on the client node.\u003c/p\u003e\n\u003cp\u003eThe TLS 1.3 client decodes the extensions of a \u003ccode\u003eNewSessionTicket\u003c/code\u003e message as if they came from \u003ccode\u003eEncryptedExtensions\u003c/code\u003e. It therefore accepts a 0-length \u003ccode\u003eearly_data\u003c/code\u003e extension, a form that is only valid in \u003ccode\u003eClientHello\u003c/code\u003e and \u003ccode\u003eEncryptedExtensions\u003c/code\u003e. With \u003ccode\u003e{session_tickets, auto}\u003c/code\u003e, the client stores the ticket in the node-global \u003ccode\u003etls_client_ticket_store\u003c/code\u003e. On the next automatic resumption, \u003ccode\u003etls_handshake_1_3:get_max_early_data/1\u003c/code\u003e crashes the store with a \u003ccode\u003ecase_clause\u003c/code\u003e. Repeated crashes can exceed the restart intensity of the \u003ccode\u003essl\u003c/code\u003e supervisors, which use the \u003ccode\u003erest_for_one\u003c/code\u003e strategy, and take down \u003ccode\u003essl\u003c/code\u003e for all connections on the node.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;23.3 before OTP\u0026nbsp;27.3.4.19, OTP\u0026nbsp;28.5.0.8, and OTP\u0026nbsp;29.1.2, corresponding to ssl from 10.3 before 11.2.12.14, 11.6.0.7, and 11.7.8.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Validation of Consistency within Input vulnerability in Erlang OTP ssl (`tls_handshake_1_3`, `ssl_handshake` and `tls_client_ticket_store` modules) allows a malicious TLS 1.3 server to cause a denial of service of the `ssl` application on the client node.\n\nThe TLS 1.3 client decodes the extensions of a `NewSessionTicket` message as if they came from `EncryptedExtensions`. It therefore accepts a 0-length `early_data` extension, a form that is only valid in `ClientHello` and `EncryptedExtensions`. With `{session_tickets, auto}`, the client stores the ticket in the node-global `tls_client_ticket_store`. On the next automatic resumption, `tls_handshake_1_3:get_max_early_data/1` crashes the store with a `case_clause`. Repeated crashes can exceed the restart intensity of the `ssl` supervisors, which use the `rest_for_one` strategy, and take down `ssl` for all connections on the node.\n\nThis issue affects OTP from OTP\u00a023.3 before OTP\u00a027.3.4.19, OTP\u00a028.5.0.8, and OTP\u00a029.1.2, corresponding to ssl from 10.3 before 11.2.12.14, 11.6.0.7, and 11.7.8."
}
],
"value": "Improper Validation of Consistency within Input vulnerability in Erlang OTP ssl (tls_handshake_1_3, ssl_handshake and tls_client_ticket_store modules) allows a malicious TLS 1.3 server to cause a denial of service of the ssl application on the client node.\n\nThe TLS 1.3 client decodes the extensions of a NewSessionTicket message as if they came from EncryptedExtensions. It therefore accepts a 0-length early_data extension, a form that is only valid in ClientHello and EncryptedExtensions. With {session_tickets, auto}, the client stores the ticket in the node-global tls_client_ticket_store. On the next automatic resumption, tls_handshake_1_3:get_max_early_data/1 crashes the store with a case_clause. Repeated crashes can exceed the restart intensity of the ssl supervisors, which use the rest_for_one strategy, and take down ssl for all connections on the node.\n\nThis issue affects OTP from OTP\u00a023.3 before OTP\u00a027.3.4.19, OTP\u00a028.5.0.8, and OTP\u00a029.1.2, corresponding to ssl from 10.3 before 11.2.12.14, 11.6.0.7, and 11.7.8."
}
],
"impacts": [
{
"capecId": "CAPEC-153",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eA malicious TLS 1.3 server can crash the client node\u0027s session ticket store, and by repeating the attack it can stop the \u003ccode\u003essl\u003c/code\u003e application for all TLS connections on that node. Only clients that use \u003ccode\u003e{session_tickets, auto}\u003c/code\u003e are affected.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "A malicious TLS 1.3 server can crash the client node\u0027s session ticket store, and by repeating the attack it can stop the `ssl` application for all TLS connections on that node. Only clients that use `{session_tickets, auto}` are affected."
}
],
"value": "A malicious TLS 1.3 server can crash the client node\u0027s session ticket store, and by repeating the attack it can stop the ssl application for all TLS connections on that node. Only clients that use {session_tickets, auto} are affected."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.2,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-1288",
"description": "CWE-1288 Improper Validation of Consistency within Input",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-10-14T16:55:23.328Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-m5mh-q53w-67jq"
},
{
"name": "EEF CNA record for CVE-2026-94200",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-94200.html"
},
{
"name": "OSV record EEF-CVE-2026-94200",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-94200"
},
{
"name": "Erlang/OTP version ordering",
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"name": "Introducing commit 0abe6f6 in erlang/otp",
"tags": [
"related"
],
"url": "https://github.com/erlang/otp/commit/0abe6f66db0d295cd06b0efab3bdb3caa2803930"
},
{
"name": "Fix commit 66febc1 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/66febc190e6dc42a5c4aedbfe250bf9a2edc2d5e"
},
{
"name": "Fix commit 00a333b in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/00a333bcf2800b69f540369b54167e897dae7219"
},
{
"name": "Fix commit cd03348 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/cd0334854bf3ef56dc16f9fb728efe88fb05c4ac"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "TLS 1.3 client ticket store crashed by NewSessionTicket with empty early_data extension in ssl",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eDo not set \u003ccode\u003e{session_tickets, auto}\u003c/code\u003e on TLS 1.3 clients. Use \u003ccode\u003emanual\u003c/code\u003e ticket handling, or keep the default value \u003ccode\u003edisabled\u003c/code\u003e.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Do not set `{session_tickets, auto}` on TLS 1.3 clients. Use `manual` ticket handling, or keep the default value `disabled`."
}
],
"value": "Do not set {session_tickets, auto} on TLS 1.3 clients. Use manual ticket handling, or keep the default value disabled."
}
],
"x_technicalAnalysis": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003e\u003cstrong\u003e1. Decoding.\u003c/strong\u003e \u003ccode\u003etls_handshake_1_3:decode_handshake/2\u003c/code\u003e decodes the extensions of a \u003ccode\u003eNewSessionTicket\u003c/code\u003e with the message type \u003ccode\u003eencrypted_extensions\u003c/code\u003e. \u003ccode\u003essl_handshake:decode_extensions/4\u003c/code\u003e does not check the message type for most extensions. A 0-length \u003ccode\u003eearly_data\u003c/code\u003e extension therefore decodes to \u003ccode\u003e#early_data_indication{}\u003c/code\u003e, the \u003ccode\u003eClientHello\u003c/code\u003e and \u003ccode\u003eEncryptedExtensions\u003c/code\u003e form, and not to \u003ccode\u003e#early_data_indication_nst{}\u003c/code\u003e, the 4-byte \u003ccode\u003emax_early_data_size\u003c/code\u003e form that RFC 8446 requires in a \u003ccode\u003eNewSessionTicket\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e2. Storage.\u003c/strong\u003e In \u003ccode\u003eauto\u003c/code\u003e mode the client sends the ticket to the node-global \u003ccode\u003etls_client_ticket_store\u003c/code\u003e gen_server, which keeps it for later resumption.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e3. Crash.\u003c/strong\u003e When a later connection resumes automatically, the store calls \u003ccode\u003etls_handshake_1_3:get_max_early_data/1\u003c/code\u003e on the stored extensions, from \u003ccode\u003emaybe_use_ticket\u003c/code\u003e and \u003ccode\u003eget_tickets\u003c/code\u003e. That function only handles \u003ccode\u003eundefined\u003c/code\u003e and \u003ccode\u003e#early_data_indication_nst{}\u003c/code\u003e, so the store process crashes with a \u003ccode\u003ecase_clause\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e4. Escalation.\u003c/strong\u003e The store is a \u003ccode\u003epermanent\u003c/code\u003e child of \u003ccode\u003essl_admin_sup\u003c/code\u003e. Each restart of the store also restarts the children after it, because the supervisor uses \u003ccode\u003erest_for_one\u003c/code\u003e. A server that keeps sending the malformed ticket makes the crashes repeat. When the crashes exceed the supervisor restart intensity, the failure goes up through \u003ccode\u003essl_sup\u003c/code\u003e and stops the \u003ccode\u003essl\u003c/code\u003e application for the whole node.\u003c/p\u003e\n\u003cp\u003eThe fix makes \u003ccode\u003essl_handshake:decode_extensions/4\u003c/code\u003e accept each extension form only in the handshake messages where it is permitted, and decodes \u003ccode\u003eNewSessionTicket\u003c/code\u003e extensions with the message type \u003ccode\u003enew_session_ticket\u003c/code\u003e.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "**1. Decoding.** `tls_handshake_1_3:decode_handshake/2` decodes the extensions of a `NewSessionTicket` with the message type `encrypted_extensions`. `ssl_handshake:decode_extensions/4` does not check the message type for most extensions. A 0-length `early_data` extension therefore decodes to `#early_data_indication{}`, the `ClientHello` and `EncryptedExtensions` form, and not to `#early_data_indication_nst{}`, the 4-byte `max_early_data_size` form that RFC 8446 requires in a `NewSessionTicket`.\n\n**2. Storage.** In `auto` mode the client sends the ticket to the node-global `tls_client_ticket_store` gen_server, which keeps it for later resumption.\n\n**3. Crash.** When a later connection resumes automatically, the store calls `tls_handshake_1_3:get_max_early_data/1` on the stored extensions, from `maybe_use_ticket` and `get_tickets`. That function only handles `undefined` and `#early_data_indication_nst{}`, so the store process crashes with a `case_clause`.\n\n**4. Escalation.** The store is a `permanent` child of `ssl_admin_sup`. Each restart of the store also restarts the children after it, because the supervisor uses `rest_for_one`. A server that keeps sending the malformed ticket makes the crashes repeat. When the crashes exceed the supervisor restart intensity, the failure goes up through `ssl_sup` and stops the `ssl` application for the whole node.\n\nThe fix makes `ssl_handshake:decode_extensions/4` accept each extension form only in the handshake messages where it is permitted, and decodes `NewSessionTicket` extensions with the message type `new_session_ticket`."
}
],
"value": "1. Decoding. tls_handshake_1_3:decode_handshake/2 decodes the extensions of a NewSessionTicket with the message type encrypted_extensions. ssl_handshake:decode_extensions/4 does not check the message type for most extensions. A 0-length early_data extension therefore decodes to #early_data_indication{}, the ClientHello and EncryptedExtensions form, and not to #early_data_indication_nst{}, the 4-byte max_early_data_size form that RFC 8446 requires in a NewSessionTicket.\n\n2. Storage. In auto mode the client sends the ticket to the node-global tls_client_ticket_store gen_server, which keeps it for later resumption.\n\n3. Crash. When a later connection resumes automatically, the store calls tls_handshake_1_3:get_max_early_data/1 on the stored extensions, from maybe_use_ticket and get_tickets. That function only handles undefined and #early_data_indication_nst{}, so the store process crashes with a case_clause.\n\n4. Escalation. The store is a permanent child of ssl_admin_sup. Each restart of the store also restarts the children after it, because the supervisor uses rest_for_one. A server that keeps sending the malformed ticket makes the crashes repeat. When the crashes exceed the supervisor restart intensity, the failure goes up through ssl_sup and stops the ssl application for the whole node.\n\nThe fix makes ssl_handshake:decode_extensions/4 accept each extension form only in the handshake messages where it is permitted, and decodes NewSessionTicket extensions with the message type new_session_ticket."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-94200",
"datePublished": "2026-10-14T16:55:23.328Z",
"dateReserved": "2026-09-21T12:15:01.330Z",
"dateUpdated": "2026-10-16T20:09:04.559Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-105236 (GCVE-0-2026-105236)
Vulnerability from nvd – Published: 2026-10-14 16:55 – Updated: 2026-10-16 20:09
VLAI
EPSS
VEX
Title
TLS 1.2 session resumption in ssl crosses SNI virtual-host client-certificate trust boundaries
Summary
Improper Certificate Validation vulnerability in the ssl application in Erlang/OTP allows a client that holds a certificate trusted by one SNI virtual host to authenticate to a second SNI virtual host on the same listener by resuming its TLS 1.2 session there.
A server that serves several SNI names from one listen socket through sni_fun or sni_hosts keeps one pre-TLS 1.3 session cache per listener and does not bind a cached session to the SNI name or client trust policy that established it. When an SNI option set switches to verify_peer without naming reuse_sessions, ssl_config:update_options/3 inherits the base listener's reuse_sessions value of true, so the default that disables reuse for client-authenticating servers does not apply. On an abbreviated handshake ssl_session:is_resumable/4 checks only that the cached session uses one of the current server certificates and carries some peer certificate, and never revalidates that certificate against the CA selected for the requested name. The names must share a server certificate, which is common with wildcard or multi-SAN certificates. TLS 1.3 does not use this cache and is not affected.
This issue affects OTP from OTP 18.0 before OTP 27.3.4.19, OTP 28.5.0.8, and OTP 29.1.2, corresponding to ssl from 7.0 before 11.2.12.14, 11.6.0.7, and 11.7.8.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-10-16 20:09 UTC
CWE
- CWE-295 - Improper Certificate Validation
Assigner
References
8 references
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
18.0 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
7.0 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
4fe38c4b8b2c8024afb60990e598ff823743fd54 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-105236",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-10-16T20:09:27.807992Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-10-16T20:09:49.566Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"ssl_gen_statem",
"ssl_config",
"ssl_session",
"ssl_handshake"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/ssl/src/ssl_gen_statem.erl",
"lib/ssl/src/ssl_config.erl",
"lib/ssl/src/ssl_session.erl",
"lib/ssl/src/ssl_handshake.erl"
],
"programRoutines": [
{
"name": "ssl_gen_statem:handle_sni_extension/2"
},
{
"name": "ssl_gen_statem:handle_sni_hostname/2"
},
{
"name": "ssl_gen_statem:update_ssl_options_from_sni/2"
},
{
"name": "ssl_gen_statem:fallback_options/2"
},
{
"name": "ssl_config:update_options/3"
},
{
"name": "ssl_config:opt_reuse_sessions/3"
},
{
"name": "ssl_session:server_select_session/5"
},
{
"name": "ssl_session:is_resumable/4"
},
{
"name": "ssl_session:reusable_options/2"
},
{
"name": "ssl_handshake:select_session/8"
}
],
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "27.3.4.19",
"status": "unaffected"
},
{
"at": "28.5.0.8",
"status": "unaffected"
},
{
"at": "29.1.2",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "18.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"ssl_gen_statem",
"ssl_config",
"ssl_session",
"ssl_handshake"
],
"packageName": "ssl",
"packageURL": "pkg:otp/ssl?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Fotp\u0026vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Ferlang%2Fotp.git",
"product": "OTP",
"programFiles": [
"src/ssl_gen_statem.erl",
"src/ssl_config.erl",
"src/ssl_session.erl",
"src/ssl_handshake.erl"
],
"programRoutines": [
{
"name": "ssl_gen_statem:handle_sni_extension/2"
},
{
"name": "ssl_gen_statem:handle_sni_hostname/2"
},
{
"name": "ssl_gen_statem:update_ssl_options_from_sni/2"
},
{
"name": "ssl_gen_statem:fallback_options/2"
},
{
"name": "ssl_config:update_options/3"
},
{
"name": "ssl_config:opt_reuse_sessions/3"
},
{
"name": "ssl_session:server_select_session/5"
},
{
"name": "ssl_session:is_resumable/4"
},
{
"name": "ssl_session:reusable_options/2"
},
{
"name": "ssl_handshake:select_session/8"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "11.2.12.14",
"status": "unaffected"
},
{
"at": "11.6.0.7",
"status": "unaffected"
},
{
"at": "11.7.8",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "7.0",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"ssl_gen_statem",
"ssl_config",
"ssl_session",
"ssl_handshake"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/ssl/src/ssl_gen_statem.erl",
"lib/ssl/src/ssl_config.erl",
"lib/ssl/src/ssl_session.erl",
"lib/ssl/src/ssl_handshake.erl"
],
"programRoutines": [
{
"name": "ssl_gen_statem:handle_sni_extension/2"
},
{
"name": "ssl_gen_statem:handle_sni_hostname/2"
},
{
"name": "ssl_gen_statem:update_ssl_options_from_sni/2"
},
{
"name": "ssl_gen_statem:fallback_options/2"
},
{
"name": "ssl_config:update_options/3"
},
{
"name": "ssl_config:opt_reuse_sessions/3"
},
{
"name": "ssl_session:server_select_session/5"
},
{
"name": "ssl_session:is_resumable/4"
},
{
"name": "ssl_session:reusable_options/2"
},
{
"name": "ssl_handshake:select_session/8"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "0c20f3683b3c81fd30b46047195be9b3d2c69d76",
"status": "unaffected"
},
{
"at": "4d76adbf39d547a931048544df09c3c087e56618",
"status": "unaffected"
},
{
"at": "10ee925d0fee8413f1170cc21bfcf123c8d22454",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "4fe38c4b8b2c8024afb60990e598ff823743fd54",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eExploitation requires all of the following. One TLS listener serves at least two SNI names through \u003ccode\u003esni_fun\u003c/code\u003e or \u003ccode\u003esni_hosts\u003c/code\u003e. The names use the same server certificate but select different client CAs with \u003ccode\u003everify_peer\u003c/code\u003e. TLS 1.2 or earlier is enabled. No SNI option set sets \u003ccode\u003ereuse_sessions\u003c/code\u003e to false while the base listener\u0027s effective value is true, which is the default when the base listener uses \u003ccode\u003everify_none\u003c/code\u003e. The attacker holds a client certificate that the lower-trust name accepts.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Exploitation requires all of the following. One TLS listener serves at least two SNI names through `sni_fun` or `sni_hosts`. The names use the same server certificate but select different client CAs with `verify_peer`. TLS 1.2 or earlier is enabled. No SNI option set sets `reuse_sessions` to false while the base listener\u0027s effective value is true, which is the default when the base listener uses `verify_none`. The attacker holds a client certificate that the lower-trust name accepts."
}
],
"value": "Exploitation requires all of the following. One TLS listener serves at least two SNI names through sni_fun or sni_hosts. The names use the same server certificate but select different client CAs with verify_peer. TLS 1.2 or earlier is enabled. No SNI option set sets reuse_sessions to false while the base listener\u0027s effective value is true, which is the default when the base listener uses verify_none. The attacker holds a client certificate that the lower-trust name accepts."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.19",
"versionStartIncluding": "18.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.8",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.1.2",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Yonghwa Lee / Xint by Theori"
},
{
"lang": "en",
"type": "reporter",
"value": "Yonghwa Lee / Xint by Theori"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Ingela Anderton Andin"
}
],
"dateAssigned": "2026-10-08T15:40:48.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Certificate Validation vulnerability in the ssl application in Erlang/OTP allows a client that holds a certificate trusted by one SNI virtual host to authenticate to a second SNI virtual host on the same listener by resuming its TLS 1.2 session there.\u003c/p\u003e\n\u003cp\u003eA server that serves several SNI names from one listen socket through \u003ccode\u003esni_fun\u003c/code\u003e or \u003ccode\u003esni_hosts\u003c/code\u003e keeps one pre-TLS 1.3 session cache per listener and does not bind a cached session to the SNI name or client trust policy that established it. When an SNI option set switches to \u003ccode\u003everify_peer\u003c/code\u003e without naming \u003ccode\u003ereuse_sessions\u003c/code\u003e, \u003ccode\u003essl_config:update_options/3\u003c/code\u003e inherits the base listener\u0027s \u003ccode\u003ereuse_sessions\u003c/code\u003e value of true, so the default that disables reuse for client-authenticating servers does not apply. On an abbreviated handshake \u003ccode\u003essl_session:is_resumable/4\u003c/code\u003e checks only that the cached session uses one of the current server certificates and carries some peer certificate, and never revalidates that certificate against the CA selected for the requested name. The names must share a server certificate, which is common with wildcard or multi-SAN certificates. TLS 1.3 does not use this cache and is not affected.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;18.0 before OTP\u0026nbsp;27.3.4.19, OTP\u0026nbsp;28.5.0.8, and OTP\u0026nbsp;29.1.2, corresponding to ssl from 7.0 before 11.2.12.14, 11.6.0.7, and 11.7.8.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Certificate Validation vulnerability in the ssl application in Erlang/OTP allows a client that holds a certificate trusted by one SNI virtual host to authenticate to a second SNI virtual host on the same listener by resuming its TLS 1.2 session there.\n\nA server that serves several SNI names from one listen socket through `sni_fun` or `sni_hosts` keeps one pre-TLS 1.3 session cache per listener and does not bind a cached session to the SNI name or client trust policy that established it. When an SNI option set switches to `verify_peer` without naming `reuse_sessions`, `ssl_config:update_options/3` inherits the base listener\u0027s `reuse_sessions` value of true, so the default that disables reuse for client-authenticating servers does not apply. On an abbreviated handshake `ssl_session:is_resumable/4` checks only that the cached session uses one of the current server certificates and carries some peer certificate, and never revalidates that certificate against the CA selected for the requested name. The names must share a server certificate, which is common with wildcard or multi-SAN certificates. TLS 1.3 does not use this cache and is not affected.\n\nThis issue affects OTP from OTP\u00a018.0 before OTP\u00a027.3.4.19, OTP\u00a028.5.0.8, and OTP\u00a029.1.2, corresponding to ssl from 7.0 before 11.2.12.14, 11.6.0.7, and 11.7.8."
}
],
"value": "Improper Certificate Validation vulnerability in the ssl application in Erlang/OTP allows a client that holds a certificate trusted by one SNI virtual host to authenticate to a second SNI virtual host on the same listener by resuming its TLS 1.2 session there.\n\nA server that serves several SNI names from one listen socket through sni_fun or sni_hosts keeps one pre-TLS 1.3 session cache per listener and does not bind a cached session to the SNI name or client trust policy that established it. When an SNI option set switches to verify_peer without naming reuse_sessions, ssl_config:update_options/3 inherits the base listener\u0027s reuse_sessions value of true, so the default that disables reuse for client-authenticating servers does not apply. On an abbreviated handshake ssl_session:is_resumable/4 checks only that the cached session uses one of the current server certificates and carries some peer certificate, and never revalidates that certificate against the CA selected for the requested name. The names must share a server certificate, which is common with wildcard or multi-SAN certificates. TLS 1.3 does not use this cache and is not affected.\n\nThis issue affects OTP from OTP\u00a018.0 before OTP\u00a027.3.4.19, OTP\u00a028.5.0.8, and OTP\u00a029.1.2, corresponding to ssl from 7.0 before 11.2.12.14, 11.6.0.7, and 11.7.8."
}
],
"impacts": [
{
"capecId": "CAPEC-114",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eA client holding a certificate issued by the lower-trust SNI name\u0027s CA connects to the higher-trust name as a fully authenticated mTLS peer and obtains whatever that service grants on a successful client-certificate handshake. Multi-tenant or partner-facing listeners that separate trust domains by SNI name are affected.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "A client holding a certificate issued by the lower-trust SNI name\u0027s CA connects to the higher-trust name as a fully authenticated mTLS peer and obtains whatever that service grants on a successful client-certificate handshake. Multi-tenant or partner-facing listeners that separate trust domains by SNI name are affected."
}
],
"value": "A client holding a certificate issued by the lower-trust SNI name\u0027s CA connects to the higher-trust name as a fully authenticated mTLS peer and obtains whatever that service grants on a successful client-certificate handshake. Multi-tenant or partner-facing listeners that separate trust domains by SNI name are affected."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "LOW",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-295",
"description": "CWE-295 Improper Certificate Validation",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-10-14T16:55:51.495Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-2g23-cgjh-34gq"
},
{
"name": "EEF CNA record for CVE-2026-105236",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-105236.html"
},
{
"name": "OSV record EEF-CVE-2026-105236",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-105236"
},
{
"name": "Erlang/OTP version ordering",
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"name": "Introducing commit 4fe38c4 in erlang/otp",
"tags": [
"related"
],
"url": "https://github.com/erlang/otp/commit/4fe38c4b8b2c8024afb60990e598ff823743fd54"
},
{
"name": "Fix commit 0c20f36 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/0c20f3683b3c81fd30b46047195be9b3d2c69d76"
},
{
"name": "Fix commit 4d76adb in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/4d76adbf39d547a931048544df09c3c087e56618"
},
{
"name": "Fix commit 10ee925 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/10ee925d0fee8413f1170cc21bfcf123c8d22454"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "TLS 1.2 session resumption in ssl crosses SNI virtual-host client-certificate trust boundaries",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cul\u003e\n\u003cli\u003eSet \u003ccode\u003e{reuse_sessions, false}\u003c/code\u003e in each SNI service\u0027s option set, or in the base listener options. The reporter\u0027s proof of concept confirmed that this blocks the cross-name resumption.\u003c/li\u003e\n\u003cli\u003eServe distinct SNI trust domains on separate listen sockets, which gives each its own session cache.\u003c/li\u003e\n\u003cli\u003eRestrict the listener to TLS 1.3 with \u003ccode\u003e{versions, [\u0027tlsv1.3\u0027]}\u003c/code\u003e. TLS 1.3 does not use the session-ID cache.\u003c/li\u003e\n\u003c/ul\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "- Set `{reuse_sessions, false}` in each SNI service\u0027s option set, or in the base listener options. The reporter\u0027s proof of concept confirmed that this blocks the cross-name resumption.\n- Serve distinct SNI trust domains on separate listen sockets, which gives each its own session cache.\n- Restrict the listener to TLS 1.3 with `{versions, [\u0027tlsv1.3\u0027]}`. TLS 1.3 does not use the session-ID cache."
}
],
"value": "* Set {reuse_sessions, false} in each SNI service\u0027s option set, or in the base listener options. The reporter\u0027s proof of concept confirmed that this blocks the cross-name resumption.\n* Serve distinct SNI trust domains on separate listen sockets, which gives each its own session cache.\n* Restrict the listener to TLS 1.3 with {versions, [\u0027tlsv1.3\u0027]}. TLS 1.3 does not use the session-ID cache."
}
],
"x_proofOfConcept": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003col\u003e\n\u003cli\u003eCreate one server certificate with subject alternative names \u003ccode\u003elow.test\u003c/code\u003e and \u003ccode\u003ehigh.test\u003c/code\u003e, two self-signed client CAs (\u003ccode\u003elow-ca\u003c/code\u003e, \u003ccode\u003ehigh-ca\u003c/code\u003e), and one client certificate signed by \u003ccode\u003elow-ca\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eStart an \u003ccode\u003essl:listen/2\u003c/code\u003e server on TLS 1.2 with \u003ccode\u003e{verify, verify_none}\u003c/code\u003e and an \u003ccode\u003esni_fun\u003c/code\u003e that returns \u003ccode\u003e{verify, verify_peer}\u003c/code\u003e, \u003ccode\u003e{fail_if_no_peer_cert, true}\u003c/code\u003e and the \u003ccode\u003elow-ca\u003c/code\u003e or \u003ccode\u003ehigh-ca\u003c/code\u003e \u003ccode\u003ecacertfile\u003c/code\u003e for the respective name. Do not set \u003ccode\u003ereuse_sessions\u003c/code\u003e anywhere.\u003c/li\u003e\n\u003cli\u003eConnect with \u003ccode\u003eopenssl s_client -servername high.test -tls1_2 -no_ticket\u003c/code\u003e using the low client certificate. The server rejects the handshake with \u003ccode\u003eunknown_ca\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eConnect with \u003ccode\u003e-servername low.test\u003c/code\u003e and the same certificate, saving the session with \u003ccode\u003e-sess_out\u003c/code\u003e. The handshake succeeds.\u003c/li\u003e\n\u003cli\u003eConnect with \u003ccode\u003e-servername high.test\u003c/code\u003e and \u003ccode\u003e-sess_in\u003c/code\u003e pointing at the saved session. The server resumes the session, \u003ccode\u003essl:connection_information/2\u003c/code\u003e reports \u003ccode\u003esession_resumption\u003c/code\u003e true for \u003ccode\u003ehigh.test\u003c/code\u003e, and the application behind the protected name serves the request to a client whose certificate \u003ccode\u003ehigh-ca\u003c/code\u003e never issued.\u003c/li\u003e\n\u003c/ol\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "1. Create one server certificate with subject alternative names `low.test` and `high.test`, two self-signed client CAs (`low-ca`, `high-ca`), and one client certificate signed by `low-ca`.\n2. Start an `ssl:listen/2` server on TLS 1.2 with `{verify, verify_none}` and an `sni_fun` that returns `{verify, verify_peer}`, `{fail_if_no_peer_cert, true}` and the `low-ca` or `high-ca` `cacertfile` for the respective name. Do not set `reuse_sessions` anywhere.\n3. Connect with `openssl s_client -servername high.test -tls1_2 -no_ticket` using the low client certificate. The server rejects the handshake with `unknown_ca`.\n4. Connect with `-servername low.test` and the same certificate, saving the session with `-sess_out`. The handshake succeeds.\n5. Connect with `-servername high.test` and `-sess_in` pointing at the saved session. The server resumes the session, `ssl:connection_information/2` reports `session_resumption` true for `high.test`, and the application behind the protected name serves the request to a client whose certificate `high-ca` never issued."
}
],
"value": "* Create one server certificate with subject alternative names low.test and high.test, two self-signed client CAs (low-ca, high-ca), and one client certificate signed by low-ca.\n* Start an ssl:listen/2 server on TLS 1.2 with {verify, verify_none} and an sni_fun that returns {verify, verify_peer}, {fail_if_no_peer_cert, true} and the low-ca or high-ca cacertfile for the respective name. Do not set reuse_sessions anywhere.\n* Connect with openssl s_client -servername high.test -tls1_2 -no_ticket using the low client certificate. The server rejects the handshake with unknown_ca.\n* Connect with -servername low.test and the same certificate, saving the session with -sess_out. The handshake succeeds.\n* Connect with -servername high.test and -sess_in pointing at the saved session. The server resumes the session, ssl:connection_information/2 reports session_resumption true for high.test, and the application behind the protected name serves the request to a client whose certificate high-ca never issued."
}
],
"x_technicalAnalysis": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003e\u003cstrong\u003e1. One session cache per listener.\u003c/strong\u003e \u003ccode\u003etls_socket:listen/3\u003c/code\u003e starts one pre-TLS 1.3 session-ID tracker per listen socket via \u003ccode\u003esession_id_tracker/2\u003c/code\u003e. Every SNI virtual host served from that socket shares it, and the cached \u003ccode\u003e#session{}\u003c/code\u003e record stores the peer and server certificates but no SNI name and no client trust policy.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e2. The SNI option set inherits session reuse.\u003c/strong\u003e When the ClientHello carries a server name, \u003ccode\u003essl_gen_statem:handle_sni_extension/2\u003c/code\u003e and \u003ccode\u003ehandle_sni_hostname/2\u003c/code\u003e call \u003ccode\u003eupdate_ssl_options_from_sni/2\u003c/code\u003e, which passes the base listener options as fallback into \u003ccode\u003essl_config:update_options/3\u003c/code\u003e. The base listener\u0027s \u003ccode\u003everify_none\u003c/code\u003e has already produced \u003ccode\u003ereuse_sessions = true\u003c/code\u003e. \u003ccode\u003essl_config:opt_reuse_sessions/3\u003c/code\u003e computes a \u003ccode\u003efalse\u003c/code\u003e default for \u003ccode\u003everify_peer\u003c/code\u003e, but \u003ccode\u003eget_opt_bool/4\u003c/code\u003e finds the inherited value and keeps it when the SNI option list does not mention \u003ccode\u003ereuse_sessions\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e3. Resumption does not revalidate the peer certificate.\u003c/strong\u003e On an abbreviated handshake \u003ccode\u003essl_handshake:select_session/8\u003c/code\u003e calls \u003ccode\u003essl_session:server_select_session/5\u003c/code\u003e, which accepts the cached session when \u003ccode\u003essl_session:is_resumable/4\u003c/code\u003e finds that it is marked resumable, that \u003ccode\u003eis_owncert/2\u003c/code\u003e matches one of the current server certificates, that \u003ccode\u003ereusable_options/2\u003c/code\u003e sees any cached peer certificate when \u003ccode\u003efail_if_no_peer_cert\u003c/code\u003e is set, and that the \u003ccode\u003ereuse_session\u003c/code\u003e fun agrees. Nothing compares the ClientHello server name with the name that created the session, and the cached peer certificate is not validated against the CA selected for the new name.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e4. Result.\u003c/strong\u003e A client whose certificate chains to the lower-trust name\u0027s CA completes a full handshake there, then presents the same session ID with the higher-trust server name. The server resumes the session, reports \u003ccode\u003esession_resumption\u003c/code\u003e as true and the low-trust peer certificate through \u003ccode\u003essl:peercert/1\u003c/code\u003e, and the application behind the protected name sees an authenticated mTLS peer. \u003ccode\u003eis_owncert/2\u003c/code\u003e is why both names must share a server certificate.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "**1. One session cache per listener.** `tls_socket:listen/3` starts one pre-TLS 1.3 session-ID tracker per listen socket via `session_id_tracker/2`. Every SNI virtual host served from that socket shares it, and the cached `#session{}` record stores the peer and server certificates but no SNI name and no client trust policy.\n\n**2. The SNI option set inherits session reuse.** When the ClientHello carries a server name, `ssl_gen_statem:handle_sni_extension/2` and `handle_sni_hostname/2` call `update_ssl_options_from_sni/2`, which passes the base listener options as fallback into `ssl_config:update_options/3`. The base listener\u0027s `verify_none` has already produced `reuse_sessions = true`. `ssl_config:opt_reuse_sessions/3` computes a `false` default for `verify_peer`, but `get_opt_bool/4` finds the inherited value and keeps it when the SNI option list does not mention `reuse_sessions`.\n\n**3. Resumption does not revalidate the peer certificate.** On an abbreviated handshake `ssl_handshake:select_session/8` calls `ssl_session:server_select_session/5`, which accepts the cached session when `ssl_session:is_resumable/4` finds that it is marked resumable, that `is_owncert/2` matches one of the current server certificates, that `reusable_options/2` sees any cached peer certificate when `fail_if_no_peer_cert` is set, and that the `reuse_session` fun agrees. Nothing compares the ClientHello server name with the name that created the session, and the cached peer certificate is not validated against the CA selected for the new name.\n\n**4. Result.** A client whose certificate chains to the lower-trust name\u0027s CA completes a full handshake there, then presents the same session ID with the higher-trust server name. The server resumes the session, reports `session_resumption` as true and the low-trust peer certificate through `ssl:peercert/1`, and the application behind the protected name sees an authenticated mTLS peer. `is_owncert/2` is why both names must share a server certificate."
}
],
"value": "1. One session cache per listener. tls_socket:listen/3 starts one pre-TLS 1.3 session-ID tracker per listen socket via session_id_tracker/2. Every SNI virtual host served from that socket shares it, and the cached #session{} record stores the peer and server certificates but no SNI name and no client trust policy.\n\n2. The SNI option set inherits session reuse. When the ClientHello carries a server name, ssl_gen_statem:handle_sni_extension/2 and handle_sni_hostname/2 call update_ssl_options_from_sni/2, which passes the base listener options as fallback into ssl_config:update_options/3. The base listener\u0027s verify_none has already produced reuse_sessions = true. ssl_config:opt_reuse_sessions/3 computes a false default for verify_peer, but get_opt_bool/4 finds the inherited value and keeps it when the SNI option list does not mention reuse_sessions.\n\n3. Resumption does not revalidate the peer certificate. On an abbreviated handshake ssl_handshake:select_session/8 calls ssl_session:server_select_session/5, which accepts the cached session when ssl_session:is_resumable/4 finds that it is marked resumable, that is_owncert/2 matches one of the current server certificates, that reusable_options/2 sees any cached peer certificate when fail_if_no_peer_cert is set, and that the reuse_session fun agrees. Nothing compares the ClientHello server name with the name that created the session, and the cached peer certificate is not validated against the CA selected for the new name.\n\n4. Result. A client whose certificate chains to the lower-trust name\u0027s CA completes a full handshake there, then presents the same session ID with the higher-trust server name. The server resumes the session, reports session_resumption as true and the low-trust peer certificate through ssl:peercert/1, and the application behind the protected name sees an authenticated mTLS peer. is_owncert/2 is why both names must share a server certificate."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-105236",
"datePublished": "2026-10-14T16:55:51.495Z",
"dateReserved": "2026-10-08T14:45:01.411Z",
"dateUpdated": "2026-10-16T20:09:49.566Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-105274 (GCVE-0-2026-105274)
Vulnerability from nvd – Published: 2026-10-12 16:43 – Updated: 2026-10-15 18:05
VLAI
EPSS
VEX
Title
hex_core decompresses registry and Erlang term API responses without size limits
Summary
Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in hexpm hex_core allows an untrusted repository mirror, or a server answering hex_core's API requests, to exhaust the memory of the Erlang VM running hex_core. The same code is vendored in Hex (mix_hex_repo, mix_hex_api) and rebar3 (r3_hex_repo, r3_hex_api).
hex_repo:get_names/1, hex_repo:get_versions/1, hex_repo:get_package/2 and hex_repo:get_policy/2 decompress the registry response with zlib:gunzip/1 and decode the signed envelope before verifying its signature. A mirror doesn't have the repository's private key, but it chooses the compressed bytes, so a small response decompresses into an envelope of any size before the signature check rejects it.
hex_api decodes responses with the application/vnd.hex+erlang content type through hex_safe_binary_to_term:safe_binary_to_term/1, which calls binary_to_term(Binary, [safe]). The safe option prevents atom creation, but it accepts compressed terms and doesn't limit the size of the decoded term, and the check that rejects functions and ports runs after the term has been built. The fix for CVE-2026-21619 added the safe option and that check without bounding the decoded size.
This issue affects rebar3: from 3.9.1 before 3.27.3; hex: from 2.1.0 before 2.5.2; hex_core: from 0.1.0 before 0.20.0.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-10-15 17:51 UTC
CWE
- CWE-409 - Improper Handling of Highly Compressed Data (Data Amplification)
Assigner
References
9 references
Impacted products
6 products
| Vendor | Product | Version | |
|---|---|---|---|
| erlang | rebar3 |
Affected:
3.9.1 , < 3.27.3
(semver)
cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:* |
|
| erlang | rebar3 |
Affected:
209c02ec57c2cc3207ee0174c3af3675b8dc8f79 , < 360838a22f5b3a88c0358207f2923059bcbb3afb
(git)
cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:* |
|
| hexpm | hex_core |
Affected:
0.1.0 , < 0.20.0
(semver)
cpe:2.3:a:hexpm:hex_core:*:*:*:*:*:*:*:* |
|
| hexpm | hex_core |
Affected:
fbb6d9de472e5edb8d6fb6b32a91cb266137892e , < ebe25d110717f6a3addba5232cd4a7dc1c76b628
(git)
cpe:2.3:a:hexpm:hex_core:*:*:*:*:*:*:*:* |
|
| hexpm | hex |
Affected:
2.1.0 , < 2.5.2
(semver)
cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:* |
|
| hexpm | hex |
Affected:
671f695ac548ed01f5828c2a739ecaa942b21007 , < d8b60eee97abb119d525306f048969a217d793a5
(git)
cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:* |
Date Public
2026-10-12 16:43
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-105274",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-10-15T17:51:41.556015Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-10-15T18:05:12.446Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"r3_hex_repo",
"r3_hex_api"
],
"packageName": "rebar3",
"packageURL": "pkg:otp/rebar3?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Frebar3\u0026vcs_url=repository_url=git%2Bhttps:%2F%2Fgithub.com%2Ferlang%2Frebar3.git",
"product": "rebar3",
"programFiles": [
"apps/rebar/src/vendored/r3_hex_repo.erl",
"apps/rebar/src/vendored/r3_hex_api.erl"
],
"programRoutines": [
{
"name": "r3_hex_repo:get_names/1"
},
{
"name": "r3_hex_repo:get_versions/1"
},
{
"name": "r3_hex_repo:get_package/2"
},
{
"name": "r3_hex_api:request/4"
}
],
"repo": "https://github.com/erlang/rebar3",
"vendor": "erlang",
"versions": [
{
"lessThan": "3.27.3",
"status": "affected",
"version": "3.9.1",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"r3_hex_repo",
"r3_hex_api"
],
"packageName": "erlang/rebar3",
"packageURL": "pkg:github/erlang/rebar3",
"product": "rebar3",
"programFiles": [
"apps/rebar/src/vendored/r3_hex_repo.erl",
"apps/rebar/src/vendored/r3_hex_api.erl"
],
"programRoutines": [
{
"name": "r3_hex_repo:get_names/1"
},
{
"name": "r3_hex_repo:get_versions/1"
},
{
"name": "r3_hex_repo:get_package/2"
},
{
"name": "r3_hex_api:request/4"
}
],
"repo": "https://github.com/erlang/rebar3",
"vendor": "erlang",
"versions": [
{
"lessThan": "360838a22f5b3a88c0358207f2923059bcbb3afb",
"status": "affected",
"version": "209c02ec57c2cc3207ee0174c3af3675b8dc8f79",
"versionType": "git"
}
]
},
{
"collectionURL": "https://repo.hex.pm",
"cpes": [
"cpe:2.3:a:hexpm:hex_core:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"hex_repo",
"hex_api",
"hex_safe_binary_to_term"
],
"packageName": "hex_core",
"packageURL": "pkg:hex/hex_core",
"product": "hex_core",
"programFiles": [
"src/hex_repo.erl",
"src/hex_api.erl",
"src/hex_safe_binary_to_term.erl"
],
"programRoutines": [
{
"name": "hex_repo:get_names/1"
},
{
"name": "hex_repo:get_versions/1"
},
{
"name": "hex_repo:get_package/2"
},
{
"name": "hex_repo:get_policy/2"
},
{
"name": "hex_api:request/4"
},
{
"name": "hex_safe_binary_to_term:safe_binary_to_term/1"
}
],
"repo": "https://github.com/hexpm/hex_core",
"vendor": "hexpm",
"versions": [
{
"lessThan": "0.20.0",
"status": "affected",
"version": "0.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:hexpm:hex_core:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"hex_repo",
"hex_api",
"hex_safe_binary_to_term"
],
"packageName": "hexpm/hex_core",
"packageURL": "pkg:github/hexpm/hex_core",
"product": "hex_core",
"programFiles": [
"src/hex_repo.erl",
"src/hex_api.erl",
"src/hex_safe_binary_to_term.erl"
],
"programRoutines": [
{
"name": "hex_repo:get_names/1"
},
{
"name": "hex_repo:get_versions/1"
},
{
"name": "hex_repo:get_package/2"
},
{
"name": "hex_repo:get_policy/2"
},
{
"name": "hex_api:request/4"
},
{
"name": "hex_safe_binary_to_term:safe_binary_to_term/1"
}
],
"repo": "https://github.com/hexpm/hex_core",
"vendor": "hexpm",
"versions": [
{
"lessThan": "ebe25d110717f6a3addba5232cd4a7dc1c76b628",
"status": "affected",
"version": "fbb6d9de472e5edb8d6fb6b32a91cb266137892e",
"versionType": "git"
}
]
},
{
"cpes": [
"cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"mix_hex_repo",
"mix_hex_api"
],
"packageName": "hex",
"packageURL": "pkg:otp/hex?repository_url=https:%2F%2Fgithub.com%2Fhexpm%2Fhex\u0026vcs_url=repository_url=git%2Bhttps:%2F%2Fgithub.com%2Fhexpm%2Fhex.git",
"product": "hex",
"programFiles": [
"src/mix_hex_repo.erl",
"src/mix_hex_api.erl"
],
"programRoutines": [
{
"name": "mix_hex_repo:get_names/1"
},
{
"name": "mix_hex_repo:get_versions/1"
},
{
"name": "mix_hex_repo:get_package/2"
},
{
"name": "mix_hex_repo:get_policy/2"
},
{
"name": "mix_hex_api:request/4"
}
],
"repo": "https://github.com/hexpm/hex",
"vendor": "hexpm",
"versions": [
{
"lessThan": "2.5.2",
"status": "affected",
"version": "2.1.0",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"mix_hex_repo",
"mix_hex_api"
],
"packageName": "hexpm/hex",
"packageURL": "pkg:github/hexpm/hex",
"product": "hex",
"programFiles": [
"src/mix_hex_repo.erl",
"src/mix_hex_api.erl"
],
"programRoutines": [
{
"name": "mix_hex_repo:get_names/1"
},
{
"name": "mix_hex_repo:get_versions/1"
},
{
"name": "mix_hex_repo:get_package/2"
},
{
"name": "mix_hex_repo:get_policy/2"
},
{
"name": "mix_hex_api:request/4"
}
],
"repo": "https://github.com/hexpm/hex",
"vendor": "hexpm",
"versions": [
{
"lessThan": "d8b60eee97abb119d525306f048969a217d793a5",
"status": "affected",
"version": "671f695ac548ed01f5828c2a739ecaa942b21007",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eRegistry decoding is affected when a repository\u0027s URL points at a mirror or another server the user doesn\u0027t trust with the availability of their builds, for example Hex\u0027s \u003ccode\u003eHEX_MIRROR_URL\u003c/code\u003e or \u003ccode\u003emirror_url\u003c/code\u003e and rebar3\u0027s \u003ccode\u003eHEX_MIRROR_URL\u003c/code\u003e. API decoding is affected when the API URL points at such a server or an attacker can alter API responses. Requests to repo.hex.pm and hex.pm over verified HTTPS aren\u0027t affected.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Registry decoding is affected when a repository\u0027s URL points at a mirror or another server the user doesn\u0027t trust with the availability of their builds, for example Hex\u0027s `HEX_MIRROR_URL` or `mirror_url` and rebar3\u0027s `HEX_MIRROR_URL`. API decoding is affected when the API URL points at such a server or an attacker can alter API responses. Requests to repo.hex.pm and hex.pm over verified HTTPS aren\u0027t affected."
}
],
"value": "Registry decoding is affected when a repository\u0027s URL points at a mirror or another server the user doesn\u0027t trust with the availability of their builds, for example Hex\u0027s HEX_MIRROR_URL or mirror_url and rebar3\u0027s HEX_MIRROR_URL. API decoding is affected when the API URL points at such a server or an attacker can alter API responses. Requests to repo.hex.pm and hex.pm over verified HTTPS aren\u0027t affected."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:*",
"versionEndExcluding": "3.27.3",
"versionStartIncluding": "3.9.1",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:hexpm:hex_core:*:*:*:*:*:*:*:*",
"versionEndExcluding": "0.20.0",
"versionStartIncluding": "0.1.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:hexpm:hex:*:*:*:*:*:*:*:*",
"versionEndExcluding": "2.5.2",
"versionStartIncluding": "2.1.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Eric Meadows-J\u00f6nsson"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-10-10T13:01:00.000Z",
"datePublic": "2026-10-12T16:43:59.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Handling of Highly Compressed Data (Data Amplification) vulnerability in hexpm hex_core allows an untrusted repository mirror, or a server answering hex_core\u0027s API requests, to exhaust the memory of the Erlang VM running hex_core. The same code is vendored in Hex (\u003ccode\u003emix_hex_repo\u003c/code\u003e, \u003ccode\u003emix_hex_api\u003c/code\u003e) and rebar3 (\u003ccode\u003er3_hex_repo\u003c/code\u003e, \u003ccode\u003er3_hex_api\u003c/code\u003e).\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ehex_repo:get_names/1\u003c/code\u003e, \u003ccode\u003ehex_repo:get_versions/1\u003c/code\u003e, \u003ccode\u003ehex_repo:get_package/2\u003c/code\u003e and \u003ccode\u003ehex_repo:get_policy/2\u003c/code\u003e decompress the registry response with \u003ccode\u003ezlib:gunzip/1\u003c/code\u003e and decode the signed envelope before verifying its signature. A mirror doesn\u0027t have the repository\u0027s private key, but it chooses the compressed bytes, so a small response decompresses into an envelope of any size before the signature check rejects it.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ehex_api\u003c/code\u003e decodes responses with the \u003ccode\u003eapplication/vnd.hex+erlang\u003c/code\u003e content type through \u003ccode\u003ehex_safe_binary_to_term:safe_binary_to_term/1\u003c/code\u003e, which calls \u003ccode\u003ebinary_to_term(Binary, [safe])\u003c/code\u003e. The \u003ccode\u003esafe\u003c/code\u003e option prevents atom creation, but it accepts compressed terms and doesn\u0027t limit the size of the decoded term, and the check that rejects functions and ports runs after the term has been built. The fix for CVE-2026-21619 added the \u003ccode\u003esafe\u003c/code\u003e option and that check without bounding the decoded size.\u003c/p\u003e\n\u003cp\u003eThis issue affects rebar3: from 3.9.1 before 3.27.3; hex: from 2.1.0 before 2.5.2; hex_core: from 0.1.0 before 0.20.0.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in hexpm hex_core allows an untrusted repository mirror, or a server answering hex_core\u0027s API requests, to exhaust the memory of the Erlang VM running hex_core. The same code is vendored in Hex (`mix_hex_repo`, `mix_hex_api`) and rebar3 (`r3_hex_repo`, `r3_hex_api`).\n\n`hex_repo:get_names/1`, `hex_repo:get_versions/1`, `hex_repo:get_package/2` and `hex_repo:get_policy/2` decompress the registry response with `zlib:gunzip/1` and decode the signed envelope before verifying its signature. A mirror doesn\u0027t have the repository\u0027s private key, but it chooses the compressed bytes, so a small response decompresses into an envelope of any size before the signature check rejects it.\n\n`hex_api` decodes responses with the `application/vnd.hex+erlang` content type through `hex_safe_binary_to_term:safe_binary_to_term/1`, which calls `binary_to_term(Binary, [safe])`. The `safe` option prevents atom creation, but it accepts compressed terms and doesn\u0027t limit the size of the decoded term, and the check that rejects functions and ports runs after the term has been built. The fix for CVE-2026-21619 added the `safe` option and that check without bounding the decoded size.\n\nThis issue affects rebar3: from 3.9.1 before 3.27.3; hex: from 2.1.0 before 2.5.2; hex_core: from 0.1.0 before 0.20.0."
}
],
"value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in hexpm hex_core allows an untrusted repository mirror, or a server answering hex_core\u0027s API requests, to exhaust the memory of the Erlang VM running hex_core. The same code is vendored in Hex (mix_hex_repo, mix_hex_api) and rebar3 (r3_hex_repo, r3_hex_api).\n\nhex_repo:get_names/1, hex_repo:get_versions/1, hex_repo:get_package/2 and hex_repo:get_policy/2 decompress the registry response with zlib:gunzip/1 and decode the signed envelope before verifying its signature. A mirror doesn\u0027t have the repository\u0027s private key, but it chooses the compressed bytes, so a small response decompresses into an envelope of any size before the signature check rejects it.\n\nhex_api decodes responses with the application/vnd.hex+erlang content type through hex_safe_binary_to_term:safe_binary_to_term/1, which calls binary_to_term(Binary, [safe]). The safe option prevents atom creation, but it accepts compressed terms and doesn\u0027t limit the size of the decoded term, and the check that rejects functions and ports runs after the term has been built. The fix for CVE-2026-21619 added the safe option and that check without bounding the decoded size.\n\nThis issue affects rebar3: from 3.9.1 before 3.27.3; hex: from 2.1.0 before 2.5.2; hex_core: from 0.1.0 before 0.20.0."
}
],
"impacts": [
{
"capecId": "CAPEC-130",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eA mirror can make every registry fetch allocate memory far beyond the size of its response: in a test against Hex main 851b938, which vendors this code, a 65 KB registry response decompressed into a 64 MiB envelope before the signature check failed. The API server, or an attacker who can alter its responses, can do the same with API responses: 8 KB of compressed Erlang term format decoded into a list of 4.2 million elements. Large enough responses stop the Erlang VM, which fails the build tool command or the program using hex_core. No package code has to run.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "A mirror can make every registry fetch allocate memory far beyond the size of its response: in a test against Hex main 851b938, which vendors this code, a 65 KB registry response decompressed into a 64 MiB envelope before the signature check failed. The API server, or an attacker who can alter its responses, can do the same with API responses: 8 KB of compressed Erlang term format decoded into a list of 4.2 million elements. Large enough responses stop the Erlang VM, which fails the build tool command or the program using hex_core. No package code has to run."
}
],
"value": "A mirror can make every registry fetch allocate memory far beyond the size of its response: in a test against Hex main 851b938, which vendors this code, a 65 KB registry response decompressed into a 64 MiB envelope before the signature check failed. The API server, or an attacker who can alter its responses, can do the same with API responses: 8 KB of compressed Erlang term format decoded into a list of 4.2 million elements. Large enough responses stop the Erlang VM, which fails the build tool command or the program using hex_core. No package code has to run."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 2.1,
"baseSeverity": "LOW",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "ACTIVE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "LOW",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-409",
"description": "CWE-409 Improper Handling of Highly Compressed Data (Data Amplification)",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-10-12T18:16:57.155Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/hexpm/hex_core/security/advisories/GHSA-7c4r-cgf9-9jmq"
},
{
"name": "EEF CNA record for CVE-2026-105274",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-105274.html"
},
{
"name": "OSV record EEF-CVE-2026-105274",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-105274"
},
{
"name": "Introducing commit 209c02e in erlang/rebar3",
"tags": [
"related"
],
"url": "https://github.com/erlang/rebar3/commit/209c02ec57c2cc3207ee0174c3af3675b8dc8f79"
},
{
"name": "Fix commit 360838a in erlang/rebar3",
"tags": [
"patch"
],
"url": "https://github.com/erlang/rebar3/commit/360838a22f5b3a88c0358207f2923059bcbb3afb"
},
{
"name": "Introducing commit fbb6d9d in hexpm/hex_core",
"tags": [
"related"
],
"url": "https://github.com/hexpm/hex_core/commit/fbb6d9de472e5edb8d6fb6b32a91cb266137892e"
},
{
"name": "Fix commit ebe25d1 in hexpm/hex_core",
"tags": [
"patch"
],
"url": "https://github.com/hexpm/hex_core/commit/ebe25d110717f6a3addba5232cd4a7dc1c76b628"
},
{
"name": "Introducing commit 671f695 in hexpm/hex",
"tags": [
"related"
],
"url": "https://github.com/hexpm/hex/commit/671f695ac548ed01f5828c2a739ecaa942b21007"
},
{
"name": "Fix commit d8b60ee in hexpm/hex",
"tags": [
"patch"
],
"url": "https://github.com/hexpm/hex/commit/d8b60eee97abb119d525306f048969a217d793a5"
}
],
"solutions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eUpgrade hex_core to 0.20.0 or later. Registry resources larger than 16 MiB after decompression are rejected with \u003ccode\u003e{too_big_uncompressed, MaxSize}\u003c/code\u003e, configurable with \u003ccode\u003eregistry_max_uncompressed_size\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eUpgrade Hex to 2.5.2 or later, which vendors hex_core 0.20.0. No rebar3 release vendors hex_core 0.20.0 yet.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Upgrade hex_core to 0.20.0 or later. Registry resources larger than 16 MiB after decompression are rejected with `{too_big_uncompressed, MaxSize}`, configurable with `registry_max_uncompressed_size`.\n\nUpgrade Hex to 2.5.2 or later, which vendors hex_core 0.20.0. No rebar3 release vendors hex_core 0.20.0 yet."
}
],
"value": "Upgrade hex_core to 0.20.0 or later. Registry resources larger than 16 MiB after decompression are rejected with {too_big_uncompressed, MaxSize}, configurable with registry_max_uncompressed_size.\n\nUpgrade Hex to 2.5.2 or later, which vendors hex_core 0.20.0. No rebar3 release vendors hex_core 0.20.0 yet."
}
],
"source": {
"discovery": "UNKNOWN"
},
"title": "hex_core decompresses registry and Erlang term API responses without size limits",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003ePoint repository URLs at repo.hex.pm or a mirror you operate, and the API URL at hex.pm.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Point repository URLs at repo.hex.pm or a mirror you operate, and the API URL at hex.pm."
}
],
"value": "Point repository URLs at repo.hex.pm or a mirror you operate, and the API URL at hex.pm."
}
],
"x_proofOfConcept": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003col\u003e\n\u003cli\u003ePoint a repository at a loopback mirror (in Hex, \u003ccode\u003eHEX_MIRROR_URL\u003c/code\u003e) that answers \u003ccode\u003e/packages/probe\u003c/code\u003e with a 65,268-byte gzip stream decompressing to a 67,108,872-byte signed envelope with a 64 MiB payload and a one-byte signature.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eHex.Repo.get_package(\"hexpm\", \"probe\", nil)\u003c/code\u003e, which calls the vendored \u003ccode\u003ehex_repo:get_package/2\u003c/code\u003e, returns \u003ccode\u003e{:error, :bad_signature}\u003c/code\u003e after allocating the envelope. Peak RSS was 234 MiB, against 96 MiB for a 1,030-byte invalid envelope.\u003c/li\u003e\n\u003cli\u003eAnswer an API request with \u003ccode\u003econtent-type: application/vnd.hex+erlang\u003c/code\u003e and 8,178 bytes of compressed Erlang term format encoding a list of 4,194,304 elements. \u003ccode\u003emix_hex_api:get/2\u003c/code\u003e accepts the decoded term, and BEAM memory rises from 58 MiB to 272 MiB.\u003c/li\u003e\n\u003c/ol\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "1. Point a repository at a loopback mirror (in Hex, `HEX_MIRROR_URL`) that answers `/packages/probe` with a 65,268-byte gzip stream decompressing to a 67,108,872-byte signed envelope with a 64 MiB payload and a one-byte signature.\n2. `Hex.Repo.get_package(\"hexpm\", \"probe\", nil)`, which calls the vendored `hex_repo:get_package/2`, returns `{:error, :bad_signature}` after allocating the envelope. Peak RSS was 234 MiB, against 96 MiB for a 1,030-byte invalid envelope.\n3. Answer an API request with `content-type: application/vnd.hex+erlang` and 8,178 bytes of compressed Erlang term format encoding a list of 4,194,304 elements. `mix_hex_api:get/2` accepts the decoded term, and BEAM memory rises from 58 MiB to 272 MiB."
}
],
"value": "* Point a repository at a loopback mirror (in Hex, HEX_MIRROR_URL) that answers /packages/probe with a 65,268-byte gzip stream decompressing to a 67,108,872-byte signed envelope with a 64 MiB payload and a one-byte signature.\n* Hex.Repo.get_package(\"hexpm\", \"probe\", nil), which calls the vendored hex_repo:get_package/2, returns {:error, :bad_signature} after allocating the envelope. Peak RSS was 234 MiB, against 96 MiB for a 1,030-byte invalid envelope.\n* Answer an API request with content-type: application/vnd.hex+erlang and 8,178 bytes of compressed Erlang term format encoding a list of 4,194,304 elements. mix_hex_api:get/2 accepts the decoded term, and BEAM memory rises from 58 MiB to 272 MiB."
}
],
"x_technicalAnalysis": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003col\u003e\n\u003cli\u003e\u003ccode\u003ehex_repo:get_protobuf/3\u003c/code\u003e, used by \u003ccode\u003eget_names/1\u003c/code\u003e, \u003ccode\u003eget_versions/1\u003c/code\u003e, \u003ccode\u003eget_package/2\u003c/code\u003e and \u003ccode\u003eget_policy/2\u003c/code\u003e, calls \u003ccode\u003ezlib:gunzip/1\u003c/code\u003e on the whole response body with no output limit.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehex_repo:decode/4\u003c/code\u003e then calls \u003ccode\u003ehex_registry:decode_and_verify_signed/2\u003c/code\u003e, which decodes the protobuf envelope, copying its payload and signature, before checking the signature.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ehex_api:request/4\u003c/code\u003e passes every response whose content type contains \u003ccode\u003eapplication/vnd.hex+erlang\u003c/code\u003e to \u003ccode\u003ehex_safe_binary_to_term:safe_binary_to_term/1\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003esafe_binary_to_term/1\u003c/code\u003e calls \u003ccode\u003ebinary_to_term(Binary, [safe])\u003c/code\u003e, which decompresses compressed terms and builds the whole term, and only then walks it to reject functions and ports.\u003c/li\u003e\n\u003c/ol\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "1. `hex_repo:get_protobuf/3`, used by `get_names/1`, `get_versions/1`, `get_package/2` and `get_policy/2`, calls `zlib:gunzip/1` on the whole response body with no output limit.\n2. `hex_repo:decode/4` then calls `hex_registry:decode_and_verify_signed/2`, which decodes the protobuf envelope, copying its payload and signature, before checking the signature.\n3. `hex_api:request/4` passes every response whose content type contains `application/vnd.hex+erlang` to `hex_safe_binary_to_term:safe_binary_to_term/1`.\n4. `safe_binary_to_term/1` calls `binary_to_term(Binary, [safe])`, which decompresses compressed terms and builds the whole term, and only then walks it to reject functions and ports."
}
],
"value": "* hex_repo:get_protobuf/3, used by get_names/1, get_versions/1, get_package/2 and get_policy/2, calls zlib:gunzip/1 on the whole response body with no output limit.\n* hex_repo:decode/4 then calls hex_registry:decode_and_verify_signed/2, which decodes the protobuf envelope, copying its payload and signature, before checking the signature.\n* hex_api:request/4 passes every response whose content type contains application/vnd.hex+erlang to hex_safe_binary_to_term:safe_binary_to_term/1.\n* safe_binary_to_term/1 calls binary_to_term(Binary, [safe]), which decompresses compressed terms and builds the whole term, and only then walks it to reject functions and ports."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-105274",
"datePublished": "2026-10-12T16:43:58.730Z",
"dateReserved": "2026-10-10T13:00:02.355Z",
"dateUpdated": "2026-10-15T18:05:12.446Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-103060 (GCVE-0-2026-103060)
Vulnerability from nvd – Published: 2026-10-12 15:43 – Updated: 2026-10-16 17:44
VLAI
EPSS
VEX
Title
Path traversal in rebar3 via unvalidated dependency app names
Summary
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') vulnerability in erlang rebar3 allows a malicious package publisher to delete a directory outside the project's _build directory and extract package files into it when a developer fetches dependencies.
A package release's dependencies in a Hex registry carry an app field that names the dependency's OTP application. rebar3 uses this field as the dependency's name without validating it (rebar_packages:parse_deps/1) and builds the dependency's directory from that name (rebar_app_utils:dep_to_app/7). rebar_fetch:download_source_online/2 deletes that directory with rm -rf and moves the fetched package into it. hex.pm didn't restrict the field to a directory name before 2026-10-12, so a publisher could set it to a value such as ../../../../target. When a project depends on such a release directly or transitively, rebar3 get-deps deletes the directory the name resolves to and writes the dependency's files there. This happens before the dependency's own rebar.config.script is evaluated, and get-deps compiles nothing.
This issue affects rebar3: from 3.7.0-rc1 before 3.27.2.
Severity
SSVC
Exploitation: poc
Automatable: no
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-10-16 17:43 UTC
CWE
- CWE-22 - Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
Assigner
References
5 references
| URL | Tags |
|---|---|
| https://github.com/erlang/rebar3/security/advisor… | relatedvendor-advisory |
| https://cna.erlef.org/cves/CVE-2026-103060.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-103060 | related |
| https://github.com/erlang/rebar3/commit/56b7d8897… | related |
| https://github.com/erlang/rebar3/commit/e35282b26… | patch |
Impacted products
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-103060",
"options": [
{
"Exploitation": "poc"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-10-16T17:43:00.338501Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-10-16T17:44:16.145Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"references": [
{
"tags": [
"exploit"
],
"url": "https://github.com/erlang/rebar3/security/advisories/GHSA-6ggr-r7mh-2mv8"
}
],
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"rebar_packages",
"rebar_app_utils",
"rebar_fetch"
],
"packageName": "rebar3",
"packageURL": "pkg:otp/rebar3?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Frebar3\u0026vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Ferlang%2Frebar3.git",
"product": "rebar3",
"programFiles": [
"apps/rebar/src/rebar_packages.erl",
"apps/rebar/src/rebar_app_utils.erl",
"apps/rebar/src/rebar_fetch.erl"
],
"programRoutines": [
{
"name": "rebar_packages:parse_deps/1"
},
{
"name": "rebar_app_utils:dep_to_app/7"
},
{
"name": "rebar_fetch:download_source/2"
},
{
"name": "rebar_fetch:download_source_online/2"
}
],
"repo": "https://github.com/erlang/rebar3",
"vendor": "erlang",
"versions": [
{
"lessThan": "3.27.2",
"status": "affected",
"version": "3.7.0-rc1",
"versionType": "semver"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"rebar_packages",
"rebar_app_utils",
"rebar_fetch"
],
"packageName": "erlang/rebar3",
"packageURL": "pkg:github/erlang/rebar3",
"product": "rebar3",
"programFiles": [
"apps/rebar/src/rebar_packages.erl",
"apps/rebar/src/rebar_app_utils.erl",
"apps/rebar/src/rebar_fetch.erl"
],
"programRoutines": [
{
"name": "rebar_packages:parse_deps/1"
},
{
"name": "rebar_app_utils:dep_to_app/7"
},
{
"name": "rebar_fetch:download_source/2"
},
{
"name": "rebar_fetch:download_source_online/2"
}
],
"repo": "https://github.com/erlang/rebar3",
"vendor": "erlang",
"versions": [
{
"lessThan": "e35282b26e499b1d9e8f30bba9dccd71cd8b02ba",
"status": "affected",
"version": "56b7d88975aa8da6446857cfd92de0825024bf63",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAffects projects whose dependency tree, directly or transitively, contains a package release whose registry metadata gives a dependency a crafted \u003ccode\u003eapp\u003c/code\u003e name, when dependencies are fetched with \u003ccode\u003erebar3 get-deps\u003c/code\u003e or another command that fetches dependencies. hex.pm rejects such names when a release is published since 2026-10-12, and every requirement \u003ccode\u003eapp\u003c/code\u003e name in hex.pm\u0027s public registry on 2026-10-06 was a letter followed by letters, digits, \u003ccode\u003e_\u003c/code\u003e and \u003ccode\u003e-\u003c/code\u003e. Packages on other Hex repositories are affected when the repository operator signs such metadata.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Affects projects whose dependency tree, directly or transitively, contains a package release whose registry metadata gives a dependency a crafted `app` name, when dependencies are fetched with `rebar3 get-deps` or another command that fetches dependencies. hex.pm rejects such names when a release is published since 2026-10-12, and every requirement `app` name in hex.pm\u0027s public registry on 2026-10-06 was a letter followed by letters, digits, `_` and `-`. Packages on other Hex repositories are affected when the repository operator signs such metadata."
}
],
"value": "Affects projects whose dependency tree, directly or transitively, contains a package release whose registry metadata gives a dependency a crafted app name, when dependencies are fetched with rebar3 get-deps or another command that fetches dependencies. hex.pm rejects such names when a release is published since 2026-10-12, and every requirement app name in hex.pm\u0027s public registry on 2026-10-06 was a letter followed by letters, digits, _ and -. Packages on other Hex repositories are affected when the repository operator signs such metadata."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:rebar3:*:*:*:*:*:*:*:*",
"versionEndExcluding": "3.27.2",
"versionStartIncluding": "3.7.0-rc1",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Eric Meadows-J\u00f6nsson"
},
{
"lang": "en",
"type": "analyst",
"value": "Jonatan M\u00e4nnchen / EEF"
}
],
"dateAssigned": "2026-10-07T22:04:17.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Limitation of a Pathname to a Restricted Directory (\u0027Path Traversal\u0027) vulnerability in erlang rebar3 allows a malicious package publisher to delete a directory outside the project\u0027s \u003ccode\u003e_build\u003c/code\u003e directory and extract package files into it when a developer fetches dependencies.\u003c/p\u003e\n\u003cp\u003eA package release\u0027s dependencies in a Hex registry carry an \u003ccode\u003eapp\u003c/code\u003e field that names the dependency\u0027s OTP application. rebar3 uses this field as the dependency\u0027s name without validating it (\u003ccode\u003erebar_packages:parse_deps/1\u003c/code\u003e) and builds the dependency\u0027s directory from that name (\u003ccode\u003erebar_app_utils:dep_to_app/7\u003c/code\u003e). \u003ccode\u003erebar_fetch:download_source_online/2\u003c/code\u003e deletes that directory with \u003ccode\u003erm -rf\u003c/code\u003e and moves the fetched package into it. hex.pm didn\u0027t restrict the field to a directory name before 2026-10-12, so a publisher could set it to a value such as \u003ccode\u003e../../../../target\u003c/code\u003e. When a project depends on such a release directly or transitively, \u003ccode\u003erebar3 get-deps\u003c/code\u003e deletes the directory the name resolves to and writes the dependency\u0027s files there. This happens before the dependency\u0027s own \u003ccode\u003erebar.config.script\u003c/code\u003e is evaluated, and \u003ccode\u003eget-deps\u003c/code\u003e compiles nothing.\u003c/p\u003e\n\u003cp\u003eThis issue affects rebar3: from 3.7.0-rc1 before 3.27.2.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Limitation of a Pathname to a Restricted Directory (\u0027Path Traversal\u0027) vulnerability in erlang rebar3 allows a malicious package publisher to delete a directory outside the project\u0027s `_build` directory and extract package files into it when a developer fetches dependencies.\n\nA package release\u0027s dependencies in a Hex registry carry an `app` field that names the dependency\u0027s OTP application. rebar3 uses this field as the dependency\u0027s name without validating it (`rebar_packages:parse_deps/1`) and builds the dependency\u0027s directory from that name (`rebar_app_utils:dep_to_app/7`). `rebar_fetch:download_source_online/2` deletes that directory with `rm -rf` and moves the fetched package into it. hex.pm didn\u0027t restrict the field to a directory name before 2026-10-12, so a publisher could set it to a value such as `../../../../target`. When a project depends on such a release directly or transitively, `rebar3 get-deps` deletes the directory the name resolves to and writes the dependency\u0027s files there. This happens before the dependency\u0027s own `rebar.config.script` is evaluated, and `get-deps` compiles nothing.\n\nThis issue affects rebar3: from 3.7.0-rc1 before 3.27.2."
}
],
"value": "Improper Limitation of a Pathname to a Restricted Directory (\u0027Path Traversal\u0027) vulnerability in erlang rebar3 allows a malicious package publisher to delete a directory outside the project\u0027s _build directory and extract package files into it when a developer fetches dependencies.\n\nA package release\u0027s dependencies in a Hex registry carry an app field that names the dependency\u0027s OTP application. rebar3 uses this field as the dependency\u0027s name without validating it (rebar_packages:parse_deps/1) and builds the dependency\u0027s directory from that name (rebar_app_utils:dep_to_app/7). rebar_fetch:download_source_online/2 deletes that directory with rm -rf and moves the fetched package into it. hex.pm didn\u0027t restrict the field to a directory name before 2026-10-12, so a publisher could set it to a value such as ../../../../target. When a project depends on such a release directly or transitively, rebar3 get-deps deletes the directory the name resolves to and writes the dependency\u0027s files there. This happens before the dependency\u0027s own rebar.config.script is evaluated, and get-deps compiles nothing.\n\nThis issue affects rebar3: from 3.7.0-rc1 before 3.27.2."
}
],
"impacts": [
{
"capecId": "CAPEC-126",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eA publisher of a package in a project\u0027s dependency tree can make \u003ccode\u003erebar3 get-deps\u003c/code\u003e delete a directory outside the project\u0027s \u003ccode\u003e_build\u003c/code\u003e directory that the developer\u0027s account can write, such as the project directory or its parent, and replace its contents with a dependency package\u0027s files. Replacing a directory whose contents are later run or loaded, such as a project directory whose \u003ccode\u003erebar.config.script\u003c/code\u003e the next rebar3 command there evaluates, can lead to code execution. It works when the package is a transitive dependency and needs no compilation. Developers, CI jobs and dependency update bots that fetch dependencies with rebar3 are affected.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "A publisher of a package in a project\u0027s dependency tree can make `rebar3 get-deps` delete a directory outside the project\u0027s `_build` directory that the developer\u0027s account can write, such as the project directory or its parent, and replace its contents with a dependency package\u0027s files. Replacing a directory whose contents are later run or loaded, such as a project directory whose `rebar.config.script` the next rebar3 command there evaluates, can lead to code execution. It works when the package is a transitive dependency and needs no compilation. Developers, CI jobs and dependency update bots that fetch dependencies with rebar3 are affected."
}
],
"value": "A publisher of a package in a project\u0027s dependency tree can make rebar3 get-deps delete a directory outside the project\u0027s _build directory that the developer\u0027s account can write, such as the project directory or its parent, and replace its contents with a dependency package\u0027s files. Replacing a directory whose contents are later run or loaded, such as a project directory whose rebar.config.script the next rebar3 command there evaluates, can lead to code execution. It works when the package is a transitive dependency and needs no compilation. Developers, CI jobs and dependency update bots that fetch dependencies with rebar3 are affected."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 7.5,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "ACTIVE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-22",
"description": "CWE-22 Improper Limitation of a Pathname to a Restricted Directory (\u0027Path Traversal\u0027)",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-10-12T15:43:57.636Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/erlang/rebar3/security/advisories/GHSA-6ggr-r7mh-2mv8"
},
{
"name": "EEF CNA record for CVE-2026-103060",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-103060.html"
},
{
"name": "OSV record EEF-CVE-2026-103060",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-103060"
},
{
"name": "Introducing commit 56b7d88 in erlang/rebar3",
"tags": [
"related"
],
"url": "https://github.com/erlang/rebar3/commit/56b7d88975aa8da6446857cfd92de0825024bf63"
},
{
"name": "Fix commit e35282b in erlang/rebar3",
"tags": [
"patch"
],
"url": "https://github.com/erlang/rebar3/commit/e35282b26e499b1d9e8f30bba9dccd71cd8b02ba"
}
],
"solutions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eUpgrade rebar3 to 3.27.2 or later, for example with \u003ccode\u003erebar3 local upgrade\u003c/code\u003e. rebar3 then fails with an error when a dependency\u0027s name, including the \u003ccode\u003eapp\u003c/code\u003e name a package release gives a dependency, isn\u0027t a letter followed by letters, digits, \u003ccode\u003e_\u003c/code\u003e and \u003ccode\u003e-\u003c/code\u003e.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Upgrade rebar3 to 3.27.2 or later, for example with `rebar3 local upgrade`. rebar3 then fails with an error when a dependency\u0027s name, including the `app` name a package release gives a dependency, isn\u0027t a letter followed by letters, digits, `_` and `-`."
}
],
"value": "Upgrade rebar3 to 3.27.2 or later, for example with rebar3 local upgrade. rebar3 then fails with an error when a dependency\u0027s name, including the app name a package release gives a dependency, isn\u0027t a letter followed by letters, digits, _ and -."
}
],
"source": {
"discovery": "UNKNOWN"
},
"title": "Path traversal in rebar3 via unvalidated dependency app names",
"x_proofOfConcept": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eReproduced with rebar3 3.27.0 on Erlang/OTP 29 against a local Hex repository, with origin and signature verification left on:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eBuild a signed local Hex repository serving \u003ccode\u003eparent\u003c/code\u003e 1.0.0, whose dependency is \u003ccode\u003e#{package =\u0026gt; \u0026lt;\u0026lt;\"evildep\"\u0026gt;\u0026gt;, requirement =\u0026gt; \u0026lt;\u0026lt;\"1.0.0\"\u0026gt;\u0026gt;, optional =\u0026gt; false, app =\u0026gt; \u0026lt;\u0026lt;\"../../../../CANARY_OUTSIDE\"\u0026gt;\u0026gt;}\u003c/code\u003e, and \u003ccode\u003eevildep\u003c/code\u003e 1.0.0.\u003c/li\u003e\n\u003cli\u003eCreate a project with \u003ccode\u003e{deps, [{parent, \"1.0.0\"}]}\u003c/code\u003e that uses the local repository, and a file \u003ccode\u003eCANARY_OUTSIDE/precious.txt\u003c/code\u003e one level above the project root.\u003c/li\u003e\n\u003cli\u003eRun \u003ccode\u003erebar3 get-deps\u003c/code\u003e. It prints \u003ccode\u003eFetching parent v1.0.0\u003c/code\u003e and then \u003ccode\u003eFetching ../../../../CANARY_OUTSIDE v1.0.0\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eCANARY_OUTSIDE/precious.txt\u003c/code\u003e is gone and \u003ccode\u003eCANARY_OUTSIDE/\u003c/code\u003e holds \u003ccode\u003eevildep\u003c/code\u003e\u0027s extracted files (\u003ccode\u003ehex_metadata.config\u003c/code\u003e, \u003ccode\u003esrc/evildep.app.src\u003c/code\u003e). No scripts, plugins or hooks are in either package.\u003c/li\u003e\n\u003c/ol\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Reproduced with rebar3 3.27.0 on Erlang/OTP 29 against a local Hex repository, with origin and signature verification left on:\n\n1. Build a signed local Hex repository serving `parent` 1.0.0, whose dependency is `#{package =\u003e \u003c\u003c\"evildep\"\u003e\u003e, requirement =\u003e \u003c\u003c\"1.0.0\"\u003e\u003e, optional =\u003e false, app =\u003e \u003c\u003c\"../../../../CANARY_OUTSIDE\"\u003e\u003e}`, and `evildep` 1.0.0.\n2. Create a project with `{deps, [{parent, \"1.0.0\"}]}` that uses the local repository, and a file `CANARY_OUTSIDE/precious.txt` one level above the project root.\n3. Run `rebar3 get-deps`. It prints `Fetching parent v1.0.0` and then `Fetching ../../../../CANARY_OUTSIDE v1.0.0`.\n4. `CANARY_OUTSIDE/precious.txt` is gone and `CANARY_OUTSIDE/` holds `evildep`\u0027s extracted files (`hex_metadata.config`, `src/evildep.app.src`). No scripts, plugins or hooks are in either package."
}
],
"value": "Reproduced with rebar3 3.27.0 on Erlang/OTP 29 against a local Hex repository, with origin and signature verification left on:\n\n* Build a signed local Hex repository serving parent 1.0.0, whose dependency is #{package =\u003e \u003c\u003c\"evildep\"\u003e\u003e, requirement =\u003e \u003c\u003c\"1.0.0\"\u003e\u003e, optional =\u003e false, app =\u003e \u003c\u003c\"../../../../CANARY_OUTSIDE\"\u003e\u003e}, and evildep 1.0.0.\n* Create a project with {deps, [{parent, \"1.0.0\"}]} that uses the local repository, and a file CANARY_OUTSIDE/precious.txt one level above the project root.\n* Run rebar3 get-deps. It prints Fetching parent v1.0.0 and then Fetching ../../../../CANARY_OUTSIDE v1.0.0.\n* CANARY_OUTSIDE/precious.txt is gone and CANARY_OUTSIDE/ holds evildep\u0027s extracted files (hex_metadata.config, src/evildep.app.src). No scripts, plugins or hooks are in either package."
}
],
"x_technicalAnalysis": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003col\u003e\n\u003cli\u003ehex.pm\u0027s registry record lists each release\u0027s dependencies as maps with \u003ccode\u003epackage\u003c/code\u003e, \u003ccode\u003erequirement\u003c/code\u003e, \u003ccode\u003eoptional\u003c/code\u003e, \u003ccode\u003eapp\u003c/code\u003e and \u003ccode\u003erepository\u003c/code\u003e. The \u003ccode\u003eapp\u003c/code\u003e value comes from the publisher\u0027s package metadata and hex.pm doesn\u0027t restrict it to a directory name. The record is signed with the repository\u0027s key after the publisher has chosen the value, so the signature doesn\u0027t constrain it.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003er3_hex_registry:decode_package/3\u003c/code\u003e decodes each dependency, including \u003ccode\u003eapp\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erebar_packages:parse_deps/1\u003c/code\u003e sets the dependency\u0027s name to the \u003ccode\u003eapp\u003c/code\u003e value, falling back to the package name: \u003ccode\u003e{maps:get(app, D, Name), {pkg, Name, Constraint, undefined, undefined}}\u003c/code\u003e. The name is stored in \u003ccode\u003e#package.dependencies\u003c/code\u003e and passed through \u003ccode\u003erebar_app_utils:update_source/3\u003c/code\u003e and \u003ccode\u003erebar_prv_install_deps:handle_dep/6\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erebar_app_utils:dep_to_app/7\u003c/code\u003e builds the fetch directory with \u003ccode\u003efilename:join([DepsDir, Name])\u003c/code\u003e and no check.\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003erebar_fetch:download_source_online/2\u003c/code\u003e runs \u003ccode\u003erebar_file_utils:rm_rf(filename:absname(FetchDir))\u003c/code\u003e and then \u003ccode\u003erebar_file_utils:mv(TmpDir, filename:absname(FetchDir))\u003c/code\u003e. \u003ccode\u003efilename:absname/1\u003c/code\u003e doesn\u0027t collapse \u003ccode\u003e..\u003c/code\u003e segments, and on Unix \u003ccode\u003erm_rf/1\u003c/code\u003e runs \u003ccode\u003erm -rf\u003c/code\u003e through the shell with \u003ccode\u003erebar_utils:escape_chars/1\u003c/code\u003e, which doesn\u0027t escape \u003ccode\u003e/\u003c/code\u003e or \u003ccode\u003e.\u003c/code\u003e, so the \u003ccode\u003e..\u003c/code\u003e segments resolve outside the deps directory.\u003c/li\u003e\n\u003cli\u003eThe delete and overwrite happen for the dependency named by \u003ccode\u003eapp\u003c/code\u003e before its own \u003ccode\u003erebar.config.script\u003c/code\u003e is consulted (later in \u003ccode\u003erebar_fetch:download_source/2\u003c/code\u003e), and \u003ccode\u003eget-deps\u003c/code\u003e compiles nothing. rebar3 already runs publisher code during \u003ccode\u003eget-deps\u003c/code\u003e by evaluating a fetched package\u0027s \u003ccode\u003erebar.config.script\u003c/code\u003e and installing a dependency\u0027s plugins; the \u003ccode\u003eapp\u003c/code\u003e name adds a delete and overwrite outside \u003ccode\u003e_build\u003c/code\u003e for a dependency named by its parent package.\u003c/li\u003e\n\u003c/ol\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "1. hex.pm\u0027s registry record lists each release\u0027s dependencies as maps with `package`, `requirement`, `optional`, `app` and `repository`. The `app` value comes from the publisher\u0027s package metadata and hex.pm doesn\u0027t restrict it to a directory name. The record is signed with the repository\u0027s key after the publisher has chosen the value, so the signature doesn\u0027t constrain it.\n2. `r3_hex_registry:decode_package/3` decodes each dependency, including `app`.\n3. `rebar_packages:parse_deps/1` sets the dependency\u0027s name to the `app` value, falling back to the package name: `{maps:get(app, D, Name), {pkg, Name, Constraint, undefined, undefined}}`. The name is stored in `#package.dependencies` and passed through `rebar_app_utils:update_source/3` and `rebar_prv_install_deps:handle_dep/6`.\n4. `rebar_app_utils:dep_to_app/7` builds the fetch directory with `filename:join([DepsDir, Name])` and no check.\n5. `rebar_fetch:download_source_online/2` runs `rebar_file_utils:rm_rf(filename:absname(FetchDir))` and then `rebar_file_utils:mv(TmpDir, filename:absname(FetchDir))`. `filename:absname/1` doesn\u0027t collapse `..` segments, and on Unix `rm_rf/1` runs `rm -rf` through the shell with `rebar_utils:escape_chars/1`, which doesn\u0027t escape `/` or `.`, so the `..` segments resolve outside the deps directory.\n6. The delete and overwrite happen for the dependency named by `app` before its own `rebar.config.script` is consulted (later in `rebar_fetch:download_source/2`), and `get-deps` compiles nothing. rebar3 already runs publisher code during `get-deps` by evaluating a fetched package\u0027s `rebar.config.script` and installing a dependency\u0027s plugins; the `app` name adds a delete and overwrite outside `_build` for a dependency named by its parent package."
}
],
"value": "* hex.pm\u0027s registry record lists each release\u0027s dependencies as maps with package, requirement, optional, app and repository. The app value comes from the publisher\u0027s package metadata and hex.pm doesn\u0027t restrict it to a directory name. The record is signed with the repository\u0027s key after the publisher has chosen the value, so the signature doesn\u0027t constrain it.\n* r3_hex_registry:decode_package/3 decodes each dependency, including app.\n* rebar_packages:parse_deps/1 sets the dependency\u0027s name to the app value, falling back to the package name: {maps:get(app, D, Name), {pkg, Name, Constraint, undefined, undefined}}. The name is stored in #package.dependencies and passed through rebar_app_utils:update_source/3 and rebar_prv_install_deps:handle_dep/6.\n* rebar_app_utils:dep_to_app/7 builds the fetch directory with filename:join([DepsDir, Name]) and no check.\n* rebar_fetch:download_source_online/2 runs rebar_file_utils:rm_rf(filename:absname(FetchDir)) and then rebar_file_utils:mv(TmpDir, filename:absname(FetchDir)). filename:absname/1 doesn\u0027t collapse .. segments, and on Unix rm_rf/1 runs rm -rf through the shell with rebar_utils:escape_chars/1, which doesn\u0027t escape / or ., so the .. segments resolve outside the deps directory.\n* The delete and overwrite happen for the dependency named by app before its own rebar.config.script is consulted (later in rebar_fetch:download_source/2), and get-deps compiles nothing. rebar3 already runs publisher code during get-deps by evaluating a fetched package\u0027s rebar.config.script and installing a dependency\u0027s plugins; the app name adds a delete and overwrite outside _build for a dependency named by its parent package."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-103060",
"datePublished": "2026-10-12T15:43:57.636Z",
"dateReserved": "2026-10-06T08:45:01.521Z",
"dateUpdated": "2026-10-16T17:44:16.145Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-89422 (GCVE-0-2026-89422)
Vulnerability from nvd – Published: 2026-09-22 08:49 – Updated: 2026-09-22 13:08
VLAI
EPSS
VEX
Title
TLS 1.3 client skips server authentication when ServerHello carries an unsolicited pre_shared_key extension
Summary
Key Exchange without Entity Authentication vulnerability in Erlang/OTP ssl allows a peer that answers a TLS 1.3 client connection to impersonate the intended server. A pre_shared_key extension in the ServerHello that the client never offered causes the client to complete the handshake without validating the server's certificate, so ssl:connect returns {ok, Socket} against a peer holding no certificate, no private key and no prior session.
tls_client_connection_1_3:handle_server_hello/2 passes the received extension to tls_gen_connection_1_3:handle_resumption/2, which sets resumption = true on its mere presence without checking that the client offered a PSK. tls_handshake_1_3:get_pre_shared_key/4 meanwhile falls back to the all-zero "no PSK" value and keys the handshake with the ordinary non-PSK schedule, so the attacker's own ephemeral key suffices. The resumption flag then routes maybe_resumption/1 straight to wait_finished, skipping the certificate-handling states, so certificate path validation, verify_fun, hostname verification, partial_chain, CRL checking and OCSP stapling are all bypassed. The default client configuration is affected; clients restricted to TLS 1.2 are not.
This issue affects OTP from OTP 22.2 before OTP 27.3.4.18, OTP 28.5.0.7, and OTP 29.1.1, corresponding to ssl from 9.5 before 11.2.12.13, 11.6.0.6, and 11.7.7.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-22 13:08 UTC
CWE
- CWE-322 - Key Exchange without Entity Authentication
Assigner
References
8 references
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
22.2 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
9.5 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
21b8a1b0ad0adf200682b3854bc50114ab2b8c62 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-89422",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-22T13:08:04.474621Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-22T13:08:15.912Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"tls_client_connection_1_3",
"tls_gen_connection_1_3",
"tls_handshake_1_3"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/ssl/src/tls_client_connection_1_3.erl",
"lib/ssl/src/tls_gen_connection_1_3.erl",
"lib/ssl/src/tls_handshake_1_3.erl"
],
"programRoutines": [
{
"name": "tls_client_connection_1_3:handle_server_hello/2"
},
{
"name": "tls_client_connection_1_3:handle_encrypted_extensions/2"
},
{
"name": "tls_client_connection_1_3:maybe_resumption/1"
},
{
"name": "tls_gen_connection_1_3:handle_resumption/2"
},
{
"name": "tls_handshake_1_3:get_pre_shared_key/4"
}
],
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "27.3.4.18",
"status": "unaffected"
},
{
"at": "28.5.0.7",
"status": "unaffected"
},
{
"at": "29.1.1",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "22.2",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"tls_client_connection_1_3",
"tls_gen_connection_1_3",
"tls_handshake_1_3"
],
"packageName": "ssl",
"packageURL": "pkg:otp/ssl?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Fotp\u0026vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Ferlang%2Fotp.git",
"product": "OTP",
"programFiles": [
"src/tls_client_connection_1_3.erl",
"src/tls_gen_connection_1_3.erl",
"src/tls_handshake_1_3.erl"
],
"programRoutines": [
{
"name": "tls_client_connection_1_3:handle_server_hello/2"
},
{
"name": "tls_client_connection_1_3:handle_encrypted_extensions/2"
},
{
"name": "tls_client_connection_1_3:maybe_resumption/1"
},
{
"name": "tls_gen_connection_1_3:handle_resumption/2"
},
{
"name": "tls_handshake_1_3:get_pre_shared_key/4"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "11.2.12.13",
"status": "unaffected"
},
{
"at": "11.6.0.6",
"status": "unaffected"
},
{
"at": "11.7.7",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "9.5",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"tls_client_connection_1_3",
"tls_gen_connection_1_3",
"tls_handshake_1_3"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/ssl/src/tls_client_connection_1_3.erl",
"lib/ssl/src/tls_gen_connection_1_3.erl",
"lib/ssl/src/tls_handshake_1_3.erl"
],
"programRoutines": [
{
"name": "tls_client_connection_1_3:handle_server_hello/2"
},
{
"name": "tls_client_connection_1_3:handle_encrypted_extensions/2"
},
{
"name": "tls_client_connection_1_3:maybe_resumption/1"
},
{
"name": "tls_gen_connection_1_3:handle_resumption/2"
},
{
"name": "tls_handshake_1_3:get_pre_shared_key/4"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "afec5156361bb50d3607c7c1a453c19b9149b324",
"status": "unaffected"
},
{
"at": "98c66c858113949c4262d26cd7d426c4b09d2b35",
"status": "unaffected"
},
{
"at": "fd1d9d07fc92ec0d59f96dfb66182195882bb7dd",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "21b8a1b0ad0adf200682b3854bc50114ab2b8c62",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.18",
"versionStartIncluding": "22.2",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.7",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.1.1",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Milad Nasr / Anthropic"
},
{
"lang": "en",
"type": "finder",
"value": "Luna Tong / Anthropic"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Ingela Andin"
}
],
"dateAssigned": "2026-09-16T10:27:13.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eKey Exchange without Entity Authentication vulnerability in Erlang/OTP ssl allows a peer that answers a TLS 1.3 client connection to impersonate the intended server. A \u003ccode\u003epre_shared_key\u003c/code\u003e extension in the \u003ccode\u003eServerHello\u003c/code\u003e that the client never offered causes the client to complete the handshake without validating the server\u0027s certificate, so \u003ccode\u003essl:connect\u003c/code\u003e returns \u003ccode\u003e{ok, Socket}\u003c/code\u003e against a peer holding no certificate, no private key and no prior session.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003etls_client_connection_1_3:handle_server_hello/2\u003c/code\u003e passes the received extension to \u003ccode\u003etls_gen_connection_1_3:handle_resumption/2\u003c/code\u003e, which sets \u003ccode\u003eresumption = true\u003c/code\u003e on its mere presence without checking that the client offered a PSK. \u003ccode\u003etls_handshake_1_3:get_pre_shared_key/4\u003c/code\u003e meanwhile falls back to the all-zero \"no PSK\" value and keys the handshake with the ordinary non-PSK schedule, so the attacker\u0027s own ephemeral key suffices. The resumption flag then routes \u003ccode\u003emaybe_resumption/1\u003c/code\u003e straight to \u003ccode\u003ewait_finished\u003c/code\u003e, skipping the certificate-handling states, so certificate path validation, \u003ccode\u003everify_fun\u003c/code\u003e, hostname verification, \u003ccode\u003epartial_chain\u003c/code\u003e, CRL checking and OCSP stapling are all bypassed. The default client configuration is affected; clients restricted to TLS 1.2 are not.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;22.2 before OTP\u0026nbsp;27.3.4.18, OTP\u0026nbsp;28.5.0.7, and OTP\u0026nbsp;29.1.1, corresponding to ssl from 9.5 before 11.2.12.13, 11.6.0.6, and 11.7.7.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Key Exchange without Entity Authentication vulnerability in Erlang/OTP ssl allows a peer that answers a TLS 1.3 client connection to impersonate the intended server. A `pre_shared_key` extension in the `ServerHello` that the client never offered causes the client to complete the handshake without validating the server\u0027s certificate, so `ssl:connect` returns `{ok, Socket}` against a peer holding no certificate, no private key and no prior session.\n\n`tls_client_connection_1_3:handle_server_hello/2` passes the received extension to `tls_gen_connection_1_3:handle_resumption/2`, which sets `resumption = true` on its mere presence without checking that the client offered a PSK. `tls_handshake_1_3:get_pre_shared_key/4` meanwhile falls back to the all-zero \"no PSK\" value and keys the handshake with the ordinary non-PSK schedule, so the attacker\u0027s own ephemeral key suffices. The resumption flag then routes `maybe_resumption/1` straight to `wait_finished`, skipping the certificate-handling states, so certificate path validation, `verify_fun`, hostname verification, `partial_chain`, CRL checking and OCSP stapling are all bypassed. The default client configuration is affected; clients restricted to TLS 1.2 are not.\n\nThis issue affects OTP from OTP\u00a022.2 before OTP\u00a027.3.4.18, OTP\u00a028.5.0.7, and OTP\u00a029.1.1, corresponding to ssl from 9.5 before 11.2.12.13, 11.6.0.6, and 11.7.7."
}
],
"value": "Key Exchange without Entity Authentication vulnerability in Erlang/OTP ssl allows a peer that answers a TLS 1.3 client connection to impersonate the intended server. A pre_shared_key extension in the ServerHello that the client never offered causes the client to complete the handshake without validating the server\u0027s certificate, so ssl:connect returns {ok, Socket} against a peer holding no certificate, no private key and no prior session.\n\ntls_client_connection_1_3:handle_server_hello/2 passes the received extension to tls_gen_connection_1_3:handle_resumption/2, which sets resumption = true on its mere presence without checking that the client offered a PSK. tls_handshake_1_3:get_pre_shared_key/4 meanwhile falls back to the all-zero \"no PSK\" value and keys the handshake with the ordinary non-PSK schedule, so the attacker\u0027s own ephemeral key suffices. The resumption flag then routes maybe_resumption/1 straight to wait_finished, skipping the certificate-handling states, so certificate path validation, verify_fun, hostname verification, partial_chain, CRL checking and OCSP stapling are all bypassed. The default client configuration is affected; clients restricted to TLS 1.2 are not.\n\nThis issue affects OTP from OTP\u00a022.2 before OTP\u00a027.3.4.18, OTP\u00a028.5.0.7, and OTP\u00a029.1.1, corresponding to ssl from 9.5 before 11.2.12.13, 11.6.0.6, and 11.7.7."
}
],
"impacts": [
{
"capecId": "CAPEC-94",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAn attacker that answers a TLS 1.3 client connection, either as the host the client dials or as an on-path attacker, completes the handshake as the intended server and holds all traffic keys. It can read everything the application sends, including credentials, tokens and request bodies, and forge every response. Any consumer of \u003ccode\u003essl:connect\u003c/code\u003e that negotiates TLS 1.3 is affected, including \u003ccode\u003ehttpc\u003c/code\u003e over HTTPS, database and messaging client libraries, and TLS distribution clients.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "An attacker that answers a TLS 1.3 client connection, either as the host the client dials or as an on-path attacker, completes the handshake as the intended server and holds all traffic keys. It can read everything the application sends, including credentials, tokens and request bodies, and forge every response. Any consumer of `ssl:connect` that negotiates TLS 1.3 is affected, including `httpc` over HTTPS, database and messaging client libraries, and TLS distribution clients."
}
],
"value": "An attacker that answers a TLS 1.3 client connection, either as the host the client dials or as an on-path attacker, completes the handshake as the intended server and holds all traffic keys. It can read everything the application sends, including credentials, tokens and request bodies, and forge every response. Any consumer of ssl:connect that negotiates TLS 1.3 is affected, including httpc over HTTPS, database and messaging client libraries, and TLS distribution clients."
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 9.3,
"baseSeverity": "CRITICAL",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-322",
"description": "CWE-322 Key Exchange without Entity Authentication",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-22T08:49:16.171Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-rgxr-4g4w-j875"
},
{
"name": "EEF CNA record for CVE-2026-89422",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-89422.html"
},
{
"name": "OSV record EEF-CVE-2026-89422",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-89422"
},
{
"name": "Erlang/OTP version ordering",
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"name": "Introducing commit 21b8a1b in erlang/otp",
"tags": [
"related"
],
"url": "https://github.com/erlang/otp/commit/21b8a1b0ad0adf200682b3854bc50114ab2b8c62"
},
{
"name": "Fix commit afec515 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/afec5156361bb50d3607c7c1a453c19b9149b324"
},
{
"name": "Fix commit 98c66c8 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/98c66c858113949c4262d26cd7d426c4b09d2b35"
},
{
"name": "Fix commit fd1d9d0 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/fd1d9d07fc92ec0d59f96dfb66182195882bb7dd"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "TLS 1.3 client skips server authentication when ServerHello carries an unsolicited pre_shared_key extension",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eRestrict affected clients to TLS 1.2 by setting \u003ccode\u003e{versions, [\u0027tlsv1.2\u0027]}\u003c/code\u003e in the client\u0027s \u003ccode\u003essl\u003c/code\u003e options. This avoids the vulnerable code path at the cost of losing TLS 1.3.\u003c/p\u003e\n\u003cp\u003eNo configuration both keeps TLS 1.3 and mitigates the issue.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Restrict affected clients to TLS 1.2 by setting `{versions, [\u0027tlsv1.2\u0027]}` in the client\u0027s `ssl` options. This avoids the vulnerable code path at the cost of losing TLS 1.3.\n\nNo configuration both keeps TLS 1.3 and mitigates the issue."
}
],
"value": "Restrict affected clients to TLS 1.2 by setting {versions, [\u0027tlsv1.2\u0027]} in the client\u0027s ssl options. This avoids the vulnerable code path at the cost of losing TLS 1.3.\n\nNo configuration both keeps TLS 1.3 and mitigates the issue."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-89422",
"datePublished": "2026-09-22T08:49:16.171Z",
"dateReserved": "2026-09-11T18:45:01.480Z",
"dateUpdated": "2026-09-22T13:08:15.912Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-68956 (GCVE-0-2026-68956)
Vulnerability from nvd – Published: 2026-09-22 08:49 – Updated: 2026-09-24 20:07
VLAI
EPSS
VEX
Title
SSH daemon allocates unbounded idle session channels, bypassing max_channels
Summary
Allocation of Resources Without Limits or Throttling vulnerability in Erlang/OTP ssh allows an authenticated remote attacker to exhaust node memory by repeatedly opening session channels that are never assigned a handler.
The "session" clause of ssh_connection:handle_msg/4 checks only minimal_remote_max_packet_size before calling setup_session/5, which unconditionally builds a #channel{} record and stores it in the ETS channel cache. The max_channels daemon option is consulted only by ssh_channel_sup:max_num_channels_not_exceeded/2, which counts supervisor children, so a channel that never gets a shell, exec, or subsystem handler is invisible to the limit and setting the option to a finite value does not mitigate the attack. RFC 4254 section 5.1 permits many session channels per connection, and each record costs only a few hundred bytes, so a single authenticated connection can accumulate channels until the node runs out of memory and the emulator terminates, affecting every application on it. No file contents, credentials, or write access are obtainable.
This issue affects OTP from OTP 18.1.2 before OTP 27.3.4.18, OTP 28.5.0.7, and OTP 29.1.1, corresponding to ssh from 4.1.1 before 5.2.11.13, 5.5.2.6, and 6.0.6. Whether OTP before OTP 18.1.2, corresponding to ssh before 4.1.1, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-22 10:12 UTC
CWE
- CWE-770 - Allocation of Resources Without Limits or Throttling
Assigner
References
8 references
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
18.1.2 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
4.1.1 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84df3d4d0278e21a36a453bfee94799f0df67c2a , < *
(git)
Unaffected: 79c2d2be17d902c5f53969b5806b725efda831be , < * (git) Unaffected: e18100975f0e5a8d59d02de00df12247a91b443b , < * (git) Unaffected: e2bbad0107bba41491a4d549686fd023db8740da , < * (git) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
Date Public
2026-09-22 08:49
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-68956",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-22T10:12:21.867151Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-22T10:25:30.750Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unknown",
"modules": [
"ssh_connection",
"ssh_channel_sup"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/ssh/src/ssh_connection.erl",
"lib/ssh/src/ssh_channel_sup.erl"
],
"programRoutines": [
{
"name": "ssh_connection:handle_msg/4"
},
{
"name": "ssh_connection:setup_session/5"
},
{
"name": "ssh_channel_sup:max_num_channels_not_exceeded/2"
}
],
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "27.3.4.18",
"status": "unaffected"
},
{
"at": "28.5.0.7",
"status": "unaffected"
},
{
"at": "29.1.1",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "18.1.2",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unknown",
"modules": [
"ssh_connection",
"ssh_channel_sup"
],
"packageName": "ssh",
"packageURL": "pkg:otp/ssh",
"product": "OTP",
"programFiles": [
"src/ssh_connection.erl",
"src/ssh_channel_sup.erl"
],
"programRoutines": [
{
"name": "ssh_connection:handle_msg/4"
},
{
"name": "ssh_connection:setup_session/5"
},
{
"name": "ssh_channel_sup:max_num_channels_not_exceeded/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "5.2.11.13",
"status": "unaffected"
},
{
"at": "5.5.2.6",
"status": "unaffected"
},
{
"at": "6.0.6",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "4.1.1",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unknown",
"modules": [
"ssh_connection",
"ssh_channel_sup"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/ssh/src/ssh_connection.erl",
"lib/ssh/src/ssh_channel_sup.erl"
],
"programRoutines": [
{
"name": "ssh_connection:handle_msg/4"
},
{
"name": "ssh_connection:setup_session/5"
},
{
"name": "ssh_channel_sup:max_num_channels_not_exceeded/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "79c2d2be17d902c5f53969b5806b725efda831be",
"status": "unaffected"
},
{
"at": "e18100975f0e5a8d59d02de00df12247a91b443b",
"status": "unaffected"
},
{
"at": "e2bbad0107bba41491a4d549686fd023db8740da",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "84df3d4d0278e21a36a453bfee94799f0df67c2a",
"versionType": "git"
},
{
"lessThan": "*",
"status": "unaffected",
"version": "79c2d2be17d902c5f53969b5806b725efda831be",
"versionType": "git"
},
{
"lessThan": "*",
"status": "unaffected",
"version": "e18100975f0e5a8d59d02de00df12247a91b443b",
"versionType": "git"
},
{
"lessThan": "*",
"status": "unaffected",
"version": "e2bbad0107bba41491a4d549686fd023db8740da",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.18",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.7",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.1.1",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "remediation developer",
"value": "Micha\u0142 W\u0105sowski / Ericsson"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Jakub Witczak / Ericsson"
}
],
"datePublic": "2026-09-22T08:49:22.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAllocation of Resources Without Limits or Throttling vulnerability in Erlang/OTP ssh allows an authenticated remote attacker to exhaust node memory by repeatedly opening session channels that are never assigned a handler.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003e\"session\"\u003c/code\u003e clause of \u003ccode\u003essh_connection:handle_msg/4\u003c/code\u003e checks only \u003ccode\u003eminimal_remote_max_packet_size\u003c/code\u003e before calling \u003ccode\u003esetup_session/5\u003c/code\u003e, which unconditionally builds a \u003ccode\u003e#channel{}\u003c/code\u003e record and stores it in the ETS channel cache. The \u003ccode\u003emax_channels\u003c/code\u003e daemon option is consulted only by \u003ccode\u003essh_channel_sup:max_num_channels_not_exceeded/2\u003c/code\u003e, which counts supervisor children, so a channel that never gets a shell, exec, or subsystem handler is invisible to the limit and setting the option to a finite value does not mitigate the attack. RFC 4254 section 5.1 permits many session channels per connection, and each record costs only a few hundred bytes, so a single authenticated connection can accumulate channels until the node runs out of memory and the emulator terminates, affecting every application on it. No file contents, credentials, or write access are obtainable.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;18.1.2 before OTP\u0026nbsp;27.3.4.18, OTP\u0026nbsp;28.5.0.7, and OTP\u0026nbsp;29.1.1, corresponding to ssh from 4.1.1 before 5.2.11.13, 5.5.2.6, and 6.0.6. Whether OTP before OTP\u0026nbsp;18.1.2, corresponding to ssh before 4.1.1, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Allocation of Resources Without Limits or Throttling vulnerability in Erlang/OTP ssh allows an authenticated remote attacker to exhaust node memory by repeatedly opening session channels that are never assigned a handler.\n\nThe `\"session\"` clause of `ssh_connection:handle_msg/4` checks only `minimal_remote_max_packet_size` before calling `setup_session/5`, which unconditionally builds a `#channel{}` record and stores it in the ETS channel cache. The `max_channels` daemon option is consulted only by `ssh_channel_sup:max_num_channels_not_exceeded/2`, which counts supervisor children, so a channel that never gets a shell, exec, or subsystem handler is invisible to the limit and setting the option to a finite value does not mitigate the attack. RFC 4254 section 5.1 permits many session channels per connection, and each record costs only a few hundred bytes, so a single authenticated connection can accumulate channels until the node runs out of memory and the emulator terminates, affecting every application on it. No file contents, credentials, or write access are obtainable.\n\nThis issue affects OTP from OTP\u00a018.1.2 before OTP\u00a027.3.4.18, OTP\u00a028.5.0.7, and OTP\u00a029.1.1, corresponding to ssh from 4.1.1 before 5.2.11.13, 5.5.2.6, and 6.0.6. Whether OTP before OTP\u00a018.1.2, corresponding to ssh before 4.1.1, is affected is unknown."
}
],
"value": "Allocation of Resources Without Limits or Throttling vulnerability in Erlang/OTP ssh allows an authenticated remote attacker to exhaust node memory by repeatedly opening session channels that are never assigned a handler.\n\nThe \"session\" clause of ssh_connection:handle_msg/4 checks only minimal_remote_max_packet_size before calling setup_session/5, which unconditionally builds a #channel{} record and stores it in the ETS channel cache. The max_channels daemon option is consulted only by ssh_channel_sup:max_num_channels_not_exceeded/2, which counts supervisor children, so a channel that never gets a shell, exec, or subsystem handler is invisible to the limit and setting the option to a finite value does not mitigate the attack. RFC 4254 section 5.1 permits many session channels per connection, and each record costs only a few hundred bytes, so a single authenticated connection can accumulate channels until the node runs out of memory and the emulator terminates, affecting every application on it. No file contents, credentials, or write access are obtainable.\n\nThis issue affects OTP from OTP\u00a018.1.2 before OTP\u00a027.3.4.18, OTP\u00a028.5.0.7, and OTP\u00a029.1.1, corresponding to ssh from 4.1.1 before 5.2.11.13, 5.5.2.6, and 6.0.6. Whether OTP before OTP\u00a018.1.2, corresponding to ssh before 4.1.1, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-125",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-125 Flooding"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 7.1,
"baseSeverity": "HIGH",
"privilegesRequired": "LOW",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-770",
"description": "CWE-770 Allocation of Resources Without Limits or Throttling",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-24T20:07:42.062Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-qhcm-px9c-rvfh"
},
{
"name": "EEF CNA record for CVE-2026-68956",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-68956.html"
},
{
"name": "OSV record EEF-CVE-2026-68956",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-68956"
},
{
"name": "Erlang/OTP version ordering",
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"name": "Introducing commit 84df3d4 in erlang/otp",
"tags": [
"related"
],
"url": "https://github.com/erlang/otp/commit/84df3d4d0278e21a36a453bfee94799f0df67c2a"
},
{
"name": "Fix commit 79c2d2b in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/79c2d2be17d902c5f53969b5806b725efda831be"
},
{
"name": "Fix commit e181009 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/e18100975f0e5a8d59d02de00df12247a91b443b"
},
{
"name": "Fix commit e2bbad0 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/e2bbad0107bba41491a4d549686fd023db8740da"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "SSH daemon allocates unbounded idle session channels, bypassing max_channels",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eNo option bounds the number of idle session channels, so the following reduce exposure without eliminating the issue.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eRestrict network access to the SSH daemon to trusted clients. Exploitation requires a successfully authenticated session, so limiting who can authenticate is the most effective control available.\u003c/li\u003e\n\u003cli\u003eSet the \u003ccode\u003emax_sessions\u003c/code\u003e daemon option to a finite value to bound the number of concurrent connections. This limits how many connections can mount the attack in parallel, though a single connection still suffices to exhaust memory.\u003c/li\u003e\n\u003cli\u003eApply operating-system or firewall connection-rate and connection-count limits per source address.\u003c/li\u003e\n\u003cli\u003eMonitor node memory externally and restart the emulator when it exceeds a threshold.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSetting \u003ccode\u003emax_channels\u003c/code\u003e is not a workaround: idle session channels bypass that check entirely.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "No option bounds the number of idle session channels, so the following reduce exposure without eliminating the issue.\n\n* Restrict network access to the SSH daemon to trusted clients. Exploitation requires a successfully authenticated session, so limiting who can authenticate is the most effective control available.\n* Set the `max_sessions` daemon option to a finite value to bound the number of concurrent connections. This limits how many connections can mount the attack in parallel, though a single connection still suffices to exhaust memory.\n* Apply operating-system or firewall connection-rate and connection-count limits per source address.\n* Monitor node memory externally and restart the emulator when it exceeds a threshold.\n\nSetting `max_channels` is not a workaround: idle session channels bypass that check entirely."
}
],
"value": "No option bounds the number of idle session channels, so the following reduce exposure without eliminating the issue.\n\n* Restrict network access to the SSH daemon to trusted clients. Exploitation requires a successfully authenticated session, so limiting who can authenticate is the most effective control available.\n* Set the max_sessions daemon option to a finite value to bound the number of concurrent connections. This limits how many connections can mount the attack in parallel, though a single connection still suffices to exhaust memory.\n* Apply operating-system or firewall connection-rate and connection-count limits per source address.\n* Monitor node memory externally and restart the emulator when it exceeds a threshold.\n\nSetting max_channels is not a workaround: idle session channels bypass that check entirely."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-68956",
"datePublished": "2026-09-22T08:49:21.760Z",
"dateReserved": "2026-08-17T13:30:02.155Z",
"dateUpdated": "2026-09-24T20:07:42.062Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-65634 (GCVE-0-2026-65634)
Vulnerability from nvd – Published: 2026-09-22 08:49 – Updated: 2026-09-24 20:06
VLAI
EPSS
VEX
Title
Superlinear CPU denial of service in Erlang/OTP ASN.1 OBJECT IDENTIFIER decoder
Summary
Inefficient algorithmic complexity in the Erlang/OTP asn1 OBJECT IDENTIFIER decoder allows a remote unauthenticated attacker to cause denial of service by sending a crafted OID during the TLS handshake.
The BER OID decoder asn1rtt_ber:dec_subidentifiers/3 in lib/asn1/src/asn1rtt_ber.erl and the equivalent PER helper asn1rtt_per_common:dec_subidentifiers/3 in lib/asn1/src/asn1rtt_per_common.erl accumulate a base-128 subidentifier into an unbounded integer using (Av bsl 7) + H per continuation byte. Each shift and addition on the growing accumulator is linear in the number of bits already accumulated, giving quadratic total work in the size of a single subidentifier. The JER helper asn1rtt_jer:json2oid/1 in lib/asn1/src/asn1rtt_jer.erl exhibits the same class of unbounded-integer parsing when decoding a dot-separated OID from JSON. A DER-encoded OBJECT IDENTIFIER with one very large arc (approximately 262 KB of continuation bytes) consumes roughly 13 seconds of CPU on typical hardware.
The vulnerable decoder is generated into every ASN.1 module that contains an OBJECT IDENTIFIER, including OTP-PUB-KEY which is reached during X.509 certificate parsing via public_key:pkix_decode_cert/2. This decoder runs before any signature or trust chain verification, so any Erlang service that parses peer TLS certificates is exposed: the default for TLS clients (which always parse the server certificate) and for mutual-TLS servers (which parse client certificates).
This vulnerability is associated with program files lib/asn1/src/asn1rtt_ber.erl, lib/asn1/src/asn1rtt_per_common.erl and lib/asn1/src/asn1rtt_jer.erl and program routines asn1rtt_ber:dec_subidentifiers/3, asn1rtt_per_common:dec_subidentifiers/3 and asn1rtt_jer:json2oid/1.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.18, OTP 28.5.0.7, and OTP 29.1.1, corresponding to asn1 from 3.0 before 5.3.4.3, 5.4.3.1, and 5.5.2. Whether OTP before OTP 17.0, corresponding to asn1 before 3.0, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-22 10:12 UTC
CWE
- CWE-407 - Inefficient Algorithmic Complexity
Assigner
References
5 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | relatedvendor-advisory |
| https://cna.erlef.org/cves/CVE-2026-65634.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-65634 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/0fe2c02fdc06… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
17.0 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
3.0 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < 0fe2c02fdc06fab1c63be9db1a7456993d20f838
(git)
Unaffected: 0fe2c02fdc06fab1c63be9db1a7456993d20f838 , < * (git) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
Date Public
2026-09-22 08:49
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-65634",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-22T10:12:07.686442Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-22T10:15:28.691Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unknown",
"modules": [
"asn1rtt_ber",
"asn1rtt_per_common",
"asn1rtt_jer"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/asn1/src/asn1rtt_ber.erl",
"lib/asn1/src/asn1rtt_per_common.erl",
"lib/asn1/src/asn1rtt_jer.erl"
],
"programRoutines": [
{
"name": "asn1rtt_ber:dec_subidentifiers/3"
},
{
"name": "asn1rtt_per_common:dec_subidentifiers/3"
},
{
"name": "asn1rtt_jer:json2oid/1"
}
],
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "27.3.4.18",
"status": "unaffected"
},
{
"at": "28.5.0.7",
"status": "unaffected"
},
{
"at": "29.1.1",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "17.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unknown",
"modules": [
"asn1rtt_ber",
"asn1rtt_per_common",
"asn1rtt_jer"
],
"packageName": "asn1",
"packageURL": "pkg:otp/asn1",
"product": "OTP",
"programFiles": [
"src/asn1rtt_ber.erl",
"src/asn1rtt_per_common.erl",
"src/asn1rtt_jer.erl"
],
"programRoutines": [
{
"name": "asn1rtt_ber:dec_subidentifiers/3"
},
{
"name": "asn1rtt_per_common:dec_subidentifiers/3"
},
{
"name": "asn1rtt_jer:json2oid/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "5.3.4.3",
"status": "unaffected"
},
{
"at": "5.4.3.1",
"status": "unaffected"
},
{
"at": "5.5.2",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "3.0",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unknown",
"modules": [
"asn1rtt_ber",
"asn1rtt_per_common",
"asn1rtt_jer"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/asn1/src/asn1rtt_ber.erl",
"lib/asn1/src/asn1rtt_per_common.erl",
"lib/asn1/src/asn1rtt_jer.erl"
],
"programRoutines": [
{
"name": "asn1rtt_ber:dec_subidentifiers/3"
},
{
"name": "asn1rtt_per_common:dec_subidentifiers/3"
},
{
"name": "asn1rtt_jer:json2oid/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "0fe2c02fdc06fab1c63be9db1a7456993d20f838",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
},
{
"lessThan": "*",
"status": "unaffected",
"version": "0fe2c02fdc06fab1c63be9db1a7456993d20f838",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.18",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.7",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.1.1",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "tynus2"
},
{
"lang": "en",
"type": "reporter",
"value": "Lukas Backstr\u00f6m"
},
{
"lang": "en",
"type": "remediation developer",
"value": "John H\u00f6gberg"
}
],
"datePublic": "2026-09-22T08:49:25.000Z",
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eInefficient algorithmic complexity in the Erlang/OTP asn1 OBJECT IDENTIFIER decoder allows a remote unauthenticated attacker to cause denial of service by sending a crafted OID during the TLS handshake.\u003c/p\u003e\n\u003cp\u003eThe BER OID decoder \u003ccode\u003easn1rtt_ber:dec_subidentifiers/3\u003c/code\u003e in \u003ccode\u003elib/asn1/src/asn1rtt_ber.erl\u003c/code\u003e and the equivalent PER helper \u003ccode\u003easn1rtt_per_common:dec_subidentifiers/3\u003c/code\u003e in \u003ccode\u003elib/asn1/src/asn1rtt_per_common.erl\u003c/code\u003e accumulate a base-128 subidentifier into an unbounded integer using \u003ccode\u003e(Av bsl 7) + H\u003c/code\u003e per continuation byte. Each shift and addition on the growing accumulator is linear in the number of bits already accumulated, giving quadratic total work in the size of a single subidentifier. The JER helper \u003ccode\u003easn1rtt_jer:json2oid/1\u003c/code\u003e in \u003ccode\u003elib/asn1/src/asn1rtt_jer.erl\u003c/code\u003e exhibits the same class of unbounded-integer parsing when decoding a dot-separated OID from JSON. A DER-encoded OBJECT IDENTIFIER with one very large arc (approximately 262 KB of continuation bytes) consumes roughly 13 seconds of CPU on typical hardware.\u003c/p\u003e\n\u003cp\u003eThe vulnerable decoder is generated into every ASN.1 module that contains an OBJECT IDENTIFIER, including \u003ccode\u003eOTP-PUB-KEY\u003c/code\u003e which is reached during X.509 certificate parsing via \u003ccode\u003epublic_key:pkix_decode_cert/2\u003c/code\u003e. This decoder runs before any signature or trust chain verification, so any Erlang service that parses peer TLS certificates is exposed: the default for TLS clients (which always parse the server certificate) and for mutual-TLS servers (which parse client certificates).\u003c/p\u003e\n\u003cp\u003eThis vulnerability is associated with program files \u003ccode\u003elib/asn1/src/asn1rtt_ber.erl\u003c/code\u003e, \u003ccode\u003elib/asn1/src/asn1rtt_per_common.erl\u003c/code\u003e and \u003ccode\u003elib/asn1/src/asn1rtt_jer.erl\u003c/code\u003e and program routines \u003ccode\u003easn1rtt_ber:dec_subidentifiers/3\u003c/code\u003e, \u003ccode\u003easn1rtt_per_common:dec_subidentifiers/3\u003c/code\u003e and \u003ccode\u003easn1rtt_jer:json2oid/1\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.18, OTP\u0026nbsp;28.5.0.7, and OTP\u0026nbsp;29.1.1, corresponding to asn1 from 3.0 before 5.3.4.3, 5.4.3.1, and 5.5.2. Whether OTP before OTP\u0026nbsp;17.0, corresponding to asn1 before 3.0, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Inefficient algorithmic complexity in the Erlang/OTP asn1 OBJECT IDENTIFIER decoder allows a remote unauthenticated attacker to cause denial of service by sending a crafted OID during the TLS handshake.\n\nThe BER OID decoder `asn1rtt_ber:dec_subidentifiers/3` in `lib/asn1/src/asn1rtt_ber.erl` and the equivalent PER helper `asn1rtt_per_common:dec_subidentifiers/3` in `lib/asn1/src/asn1rtt_per_common.erl` accumulate a base-128 subidentifier into an unbounded integer using `(Av bsl 7) + H` per continuation byte. Each shift and addition on the growing accumulator is linear in the number of bits already accumulated, giving quadratic total work in the size of a single subidentifier. The JER helper `asn1rtt_jer:json2oid/1` in `lib/asn1/src/asn1rtt_jer.erl` exhibits the same class of unbounded-integer parsing when decoding a dot-separated OID from JSON. A DER-encoded OBJECT IDENTIFIER with one very large arc (approximately 262 KB of continuation bytes) consumes roughly 13 seconds of CPU on typical hardware.\n\nThe vulnerable decoder is generated into every ASN.1 module that contains an OBJECT IDENTIFIER, including `OTP-PUB-KEY` which is reached during X.509 certificate parsing via `public_key:pkix_decode_cert/2`. This decoder runs before any signature or trust chain verification, so any Erlang service that parses peer TLS certificates is exposed: the default for TLS clients (which always parse the server certificate) and for mutual-TLS servers (which parse client certificates).\n\nThis vulnerability is associated with program files `lib/asn1/src/asn1rtt_ber.erl`, `lib/asn1/src/asn1rtt_per_common.erl` and `lib/asn1/src/asn1rtt_jer.erl` and program routines `asn1rtt_ber:dec_subidentifiers/3`, `asn1rtt_per_common:dec_subidentifiers/3` and `asn1rtt_jer:json2oid/1`.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.18, OTP\u00a028.5.0.7, and OTP\u00a029.1.1, corresponding to asn1 from 3.0 before 5.3.4.3, 5.4.3.1, and 5.5.2. Whether OTP before OTP\u00a017.0, corresponding to asn1 before 3.0, is affected is unknown."
}
],
"value": "Inefficient algorithmic complexity in the Erlang/OTP asn1 OBJECT IDENTIFIER decoder allows a remote unauthenticated attacker to cause denial of service by sending a crafted OID during the TLS handshake.\n\nThe BER OID decoder asn1rtt_ber:dec_subidentifiers/3 in lib/asn1/src/asn1rtt_ber.erl and the equivalent PER helper asn1rtt_per_common:dec_subidentifiers/3 in lib/asn1/src/asn1rtt_per_common.erl accumulate a base-128 subidentifier into an unbounded integer using (Av bsl 7) + H per continuation byte. Each shift and addition on the growing accumulator is linear in the number of bits already accumulated, giving quadratic total work in the size of a single subidentifier. The JER helper asn1rtt_jer:json2oid/1 in lib/asn1/src/asn1rtt_jer.erl exhibits the same class of unbounded-integer parsing when decoding a dot-separated OID from JSON. A DER-encoded OBJECT IDENTIFIER with one very large arc (approximately 262 KB of continuation bytes) consumes roughly 13 seconds of CPU on typical hardware.\n\nThe vulnerable decoder is generated into every ASN.1 module that contains an OBJECT IDENTIFIER, including OTP-PUB-KEY which is reached during X.509 certificate parsing via public_key:pkix_decode_cert/2. This decoder runs before any signature or trust chain verification, so any Erlang service that parses peer TLS certificates is exposed: the default for TLS clients (which always parse the server certificate) and for mutual-TLS servers (which parse client certificates).\n\nThis vulnerability is associated with program files lib/asn1/src/asn1rtt_ber.erl, lib/asn1/src/asn1rtt_per_common.erl and lib/asn1/src/asn1rtt_jer.erl and program routines asn1rtt_ber:dec_subidentifiers/3, asn1rtt_per_common:dec_subidentifiers/3 and asn1rtt_jer:json2oid/1.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.18, OTP\u00a028.5.0.7, and OTP\u00a029.1.1, corresponding to asn1 from 3.0 before 5.3.4.3, 5.4.3.1, and 5.5.2. Whether OTP before OTP\u00a017.0, corresponding to asn1 before 3.0, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-229",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-229 Serialized Data Parameter Blowup"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.2,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-407",
"description": "CWE-407 Inefficient Algorithmic Complexity",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-24T20:06:38.007Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-qghx-23m5-r55m"
},
{
"name": "EEF CNA record for CVE-2026-65634",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-65634.html"
},
{
"name": "OSV record EEF-CVE-2026-65634",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-65634"
},
{
"name": "Erlang/OTP version ordering",
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"name": "Fix commit 0fe2c02 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/0fe2c02fdc06fab1c63be9db1a7456993d20f838"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Superlinear CPU denial of service in Erlang/OTP ASN.1 OBJECT IDENTIFIER decoder"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-65634",
"datePublished": "2026-09-22T08:49:24.743Z",
"dateReserved": "2026-07-22T13:58:26.233Z",
"dateUpdated": "2026-09-24T20:06:38.007Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-75538 (GCVE-0-2026-75538)
Vulnerability from nvd – Published: 2026-09-01 14:48 – Updated: 2026-09-08 01:10
VLAI
EPSS
VEX
Title
A Signed Length Overflow in Erlang/OTP's inet TCP Driver Overflows the Receive Buffer Into BEAM VM Memory From an Unauthenticated Peer
Summary
An attacker that connects to an open Erlang TCP port that uses the inet driver with {packet,4} mode can use a signed overflow in an incorrect packet length calculation to overflow the receive buffer into the VM allocator area and beyond up to about 2 GB.
This would easily trash the allocated block's allocator metadata footer, and the next block, if any, and most likely cause the BEAM VM to crash. Utilizing this with precision enough to achieve Remote Code Execution would be extremely unfeasible.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to erts from 6.0 before 15.2.7.13, from 16.0 before 16.4.0.6, and from 17.0 before 17.0.6. Whether OTP before OTP 17.0, corresponding to erts before 6.0, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:58 UTC
Assigner
References
4 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisory |
| https://cna.erlef.org/cves/CVE-2026-75538.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-75538 | related |
| https://github.com/erlang/otp/commit/08e8efdba850… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 6.0
(otp)
Affected: 6.0 , < 15.2.7.13 (otp) Affected: 16.0 , < 16.4.0.6 (otp) Affected: 17.0 , < 17.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < 08e8efdba8500d2d6f54c6b1de1492b228017c9b
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-75538",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:58:11.549801Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:58:16.703Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "erts",
"packageURL": "pkg:otp/erts",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "6.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "15.2.7.13",
"status": "affected",
"version": "6.0",
"versionType": "otp"
},
{
"lessThan": "16.4.0.6",
"status": "affected",
"version": "16.0",
"versionType": "otp"
},
{
"lessThan": "17.0.6",
"status": "affected",
"version": "17.0",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "08e8efdba8500d2d6f54c6b1de1492b228017c9b",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Arthur Chan"
},
{
"lang": "en",
"type": "finder",
"value": "David Korczynski"
},
{
"lang": "en",
"type": "finder",
"value": "Adam Korcz"
},
{
"lang": "en",
"type": "remediation developer",
"value": "RaimoNiskanen / Ericsson"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Sverker Eriksson / Ericsson"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "John H\u00f6gberg / Ericsson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAn attacker that connects to an open Erlang TCP port that uses the inet driver with \u003ccode\u003e{packet,4}\u003c/code\u003e mode can use a signed overflow in an incorrect packet length calculation to overflow the receive buffer into the VM allocator area and beyond up to about 2 GB.\u003c/p\u003e\n\u003cp\u003eThis would easily trash the allocated block\u0027s allocator metadata footer, and the next block, if any, and most likely cause the BEAM VM to crash. Utilizing this with precision enough to achieve Remote Code Execution would be extremely unfeasible.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to erts from 6.0 before 15.2.7.13, from 16.0 before 16.4.0.6, and from 17.0 before 17.0.6. Whether OTP before OTP\u0026nbsp;17.0, corresponding to erts before 6.0, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "An attacker that connects to an open Erlang TCP port that uses the inet driver with `{packet,4}` mode can use a signed overflow in an incorrect packet length calculation to overflow the receive buffer into the VM allocator area and beyond up to about 2 GB.\n\nThis would easily trash the allocated block\u0027s allocator metadata footer, and the next block, if any, and most likely cause the BEAM VM to crash. Utilizing this with precision enough to achieve Remote Code Execution would be extremely unfeasible.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to erts from 6.0 before 15.2.7.13, from 16.0 before 16.4.0.6, and from 17.0 before 17.0.6. Whether OTP before OTP\u00a017.0, corresponding to erts before 6.0, is affected is unknown."
}
],
"value": "An attacker that connects to an open Erlang TCP port that uses the inet driver with {packet,4} mode can use a signed overflow in an incorrect packet length calculation to overflow the receive buffer into the VM allocator area and beyond up to about 2 GB.\n\nThis would easily trash the allocated block\u0027s allocator metadata footer, and the next block, if any, and most likely cause the BEAM VM to crash. Utilizing this with precision enough to achieve Remote Code Execution would be extremely unfeasible.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to erts from 6.0 before 15.2.7.13, from 16.0 before 16.4.0.6, and from 17.0 before 17.0.6. Whether OTP before OTP\u00a017.0, corresponding to erts before 6.0, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-100",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-100 Overflow Buffers"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.2,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-190",
"description": "CWE-190 Integer Overflow or Wraparound",
"lang": "en",
"type": "CWE"
}
]
},
{
"descriptions": [
{
"cweId": "CWE-122",
"description": "CWE-122 Heap-based Buffer Overflow",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:10:53.139Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-8m6r-2pj2-25pm"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-75538.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-75538"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/08e8efdba8500d2d6f54c6b1de1492b228017c9b"
}
],
"source": {
"discovery": "UNKNOWN"
},
"title": "A Signed Length Overflow in Erlang/OTP\u0027s inet TCP Driver Overflows the Receive Buffer Into BEAM VM Memory From an Unauthenticated Peer"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-75538",
"datePublished": "2026-09-01T14:48:26.309Z",
"dateReserved": "2026-08-20T10:15:01.237Z",
"dateUpdated": "2026-09-08T01:10:53.139Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-74994 (GCVE-0-2026-74994)
Vulnerability from nvd – Published: 2026-09-01 14:45 – Updated: 2026-09-08 01:10
VLAI
EPSS
VEX
Title
inets, httpd: Authentication Bypass via Directory Namespace Collapse in httpd mod_auth
Summary
The mod_auth module in OTP's inets httpd server, when configured with dets or mnesia authentication backends and multiple directory configuration blocks, collapses all directory blocks into a single shared user/group namespace. A user added to one protected directory is accepted as valid for all other protected directories on the same server instance.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP 17.0, corresponding to inets before 5.10, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:57 UTC
Assigner
References
6 references
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 5.10
(otp)
Affected: 5.10 , < 9.3.2.7 (otp) Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-74994",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:57:45.946562Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:57:51.022Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "5.10",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "5.10",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "6982e381137ede21a4e1faf5fa2dd82321691176",
"status": "unaffected"
},
{
"at": "c5ccec8ed25c70ec6557fd81277e4b2f52285c19",
"status": "unaffected"
},
{
"at": "6101cb74ff2870718c622ba7af0c100f7f2524e3",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Lukas Backstr\u00f6m / Erlang Solutions"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eThe mod_auth module in OTP\u0027s inets httpd server, when configured with dets or mnesia authentication backends and multiple directory configuration blocks, collapses all directory blocks into a single shared user/group namespace. A user added to one\nprotected directory is accepted as valid for all other protected directories on the same server instance.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u0026nbsp;17.0, corresponding to inets before 5.10, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "The mod_auth module in OTP\u0027s inets httpd server, when configured with dets or mnesia authentication backends and multiple directory configuration blocks, collapses all directory blocks into a single shared user/group namespace. A user added to one\nprotected directory is accepted as valid for all other protected directories on the same server instance.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"value": "The mod_auth module in OTP\u0027s inets httpd server, when configured with dets or mnesia authentication backends and multiple directory configuration blocks, collapses all directory blocks into a single shared user/group namespace. A user added to one protected directory is accepted as valid for all other protected directories on the same server instance.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-122",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-122 Privilege Abuse"
}
]
},
{
"capecId": "CAPEC-114",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-114 Authentication Abuse"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6,
"baseSeverity": "MEDIUM",
"privilegesRequired": "LOW",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-863",
"description": "CWE-863 Incorrect Authorization",
"lang": "en",
"type": "CWE"
}
]
},
{
"descriptions": [
{
"cweId": "CWE-1289",
"description": "CWE-1289 Improper Validation of Unsafe Equivalence in Input",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:10:39.103Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-c3cq-q8x6-547g"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-74994.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-74994"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/6982e381137ede21a4e1faf5fa2dd82321691176"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/c5ccec8ed25c70ec6557fd81277e4b2f52285c19"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/6101cb74ff2870718c622ba7af0c100f7f2524e3"
}
],
"source": {
"discovery": "UNKNOWN"
},
"title": "inets, httpd: Authentication Bypass via Directory Namespace Collapse in httpd mod_auth"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-74994",
"datePublished": "2026-09-01T14:45:57.537Z",
"dateReserved": "2026-08-17T13:00:01.418Z",
"dateUpdated": "2026-09-08T01:10:39.103Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-74835 (GCVE-0-2026-74835)
Vulnerability from nvd – Published: 2026-09-01 14:45 – Updated: 2026-09-08 01:10
VLAI
EPSS
VEX
Title
inets,httpd: Memory Exhaustion via Unenforced max_body_size During Chunked Body Reception
Summary
The inets application HTTP server httpd fails to enforce a configured body-size limit on chunked request.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP 17.0, corresponding to inets before 5.10, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:57 UTC
CWE
- CWE-770 - Allocation of Resources Without Limits or Throttling
Assigner
References
6 references
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 5.10
(otp)
Affected: 5.10 , < 9.3.2.7 (otp) Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-74835",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:57:17.154573Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:57:22.906Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "5.10",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "5.10",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "0bceff0c2987cae83d9d4a77c5ecacd6d01b8b86",
"status": "unaffected"
},
{
"at": "8e1ca42b64df6c41306affbe8dc129bdbd4042c7",
"status": "unaffected"
},
{
"at": "7f9c460d1818c2afb78fbd01f8d8b81343bbb011",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Lukas Backstr\u00f6m / Erlang Solutions"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eThe inets application HTTP server httpd fails to enforce a configured body-size limit on chunked request.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u0026nbsp;17.0, corresponding to inets before 5.10, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "The inets application HTTP server httpd fails to enforce a configured body-size limit on chunked request.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"value": "The inets application HTTP server httpd fails to enforce a configured body-size limit on chunked request.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-469",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-469 HTTP DoS"
}
]
},
{
"capecId": "CAPEC-130",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-130 Excessive Allocation"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 8.7,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-770",
"description": "CWE-770 Allocation of Resources Without Limits or Throttling",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:10:27.102Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-8qrh-x566-5xv5"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-74835.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-74835"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/0bceff0c2987cae83d9d4a77c5ecacd6d01b8b86"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/8e1ca42b64df6c41306affbe8dc129bdbd4042c7"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/7f9c460d1818c2afb78fbd01f8d8b81343bbb011"
}
],
"source": {
"discovery": "UNKNOWN"
},
"title": "inets,httpd: Memory Exhaustion via Unenforced max_body_size During Chunked Body Reception"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-74835",
"datePublished": "2026-09-01T14:45:16.377Z",
"dateReserved": "2026-08-17T12:30:01.524Z",
"dateUpdated": "2026-09-08T01:10:27.102Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-73812 (GCVE-0-2026-73812)
Vulnerability from nvd – Published: 2026-09-01 14:42 – Updated: 2026-09-08 01:10
VLAI
EPSS
VEX
Title
inets, httpd: HTTP Request Smuggling via Transfer-Encoding and Content-Length
Summary
httpd function check_header/3 rejects duplicate Content-Length (per CVE-2026-23941) but never checks for the TE+CL co-presence that RFC 9112 §6.3 identifies as a probable smuggling attempt. handle_body/3 frames by chunked and silently discards Content-Length. A CL-preferring front-end paired with chunked-preferring inets creates a classic CL.TE front-end/back-end desync.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP 17.0, corresponding to inets before 5.10, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:56 UTC
CWE
- CWE-444 - Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')
Assigner
References
4 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisory |
| https://cna.erlef.org/cves/CVE-2026-73812.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-73812 | related |
| https://github.com/erlang/otp/commit/591dc00dc99d… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 5.10
(otp)
Affected: 5.10 , < 9.3.2.7 (otp) Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < 591dc00dc99dc2a426167a3b5257c0c94bd45e91
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-73812",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:56:32.935740Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:56:45.383Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "5.10",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "5.10",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "591dc00dc99dc2a426167a3b5257c0c94bd45e91",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
},
{
"lang": "en",
"type": "finder",
"value": "Lukas Backstr\u00f6m / Erlang Solutions"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003ehttpd function check_header/3 rejects duplicate Content-Length (per CVE-2026-23941) but never checks for the TE+CL co-presence that RFC 9112 \u00a76.3 identifies as a probable smuggling attempt. handle_body/3 frames by chunked and silently discards Content-Length. A CL-preferring front-end paired with chunked-preferring inets creates a classic CL.TE front-end/back-end\ndesync.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u0026nbsp;17.0, corresponding to inets before 5.10, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "httpd function check_header/3 rejects duplicate Content-Length (per CVE-2026-23941) but never checks for the TE+CL co-presence that RFC 9112 \u00a76.3 identifies as a probable smuggling attempt. handle_body/3 frames by chunked and silently discards Content-Length. A CL-preferring front-end paired with chunked-preferring inets creates a classic CL.TE front-end/back-end\ndesync.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"value": "httpd function check_header/3 rejects duplicate Content-Length (per CVE-2026-23941) but never checks for the TE+CL co-presence that RFC 9112 \u00a76.3 identifies as a probable smuggling attempt. handle_body/3 frames by chunked and silently discards Content-Length. A CL-preferring front-end paired with chunked-preferring inets creates a classic CL.TE front-end/back-end desync.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-33",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-33 HTTP Request Smuggling"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.3,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:H/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "LOW",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-444",
"description": "CWE-444 Inconsistent Interpretation of HTTP Requests (\u0027HTTP Request/Response Smuggling\u0027)",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:10:14.000Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-7j6m-4ffg-hg46"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-73812.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-73812"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/591dc00dc99dc2a426167a3b5257c0c94bd45e91"
}
],
"source": {
"discovery": "UNKNOWN"
},
"title": "inets, httpd: HTTP Request Smuggling via Transfer-Encoding and Content-Length"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-73812",
"datePublished": "2026-09-01T14:42:42.374Z",
"dateReserved": "2026-08-17T11:00:01.498Z",
"dateUpdated": "2026-09-08T01:10:14.000Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-73276 (GCVE-0-2026-73276)
Vulnerability from nvd – Published: 2026-09-01 14:41 – Updated: 2026-09-08 01:10
VLAI
EPSS
VEX
Title
inets, httpd: HTTP Request Smuggling via Whitespace-Before-Colon Header Dropping i
Summary
Gracefulness code ignored cases that should be rejected, resulting in possible HTTP Request Smuggling opportunities.
This issue affects OTP from OTP 22.2 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 7.1.2 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:55 UTC
CWE
- CWE-444 - Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')
Assigner
References
6 references
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
22.2 , < 27.3.4.17
(otp)
Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
7.1.2 , < 9.3.2.7
(otp)
Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
c06db0bedf49a9b40725745e73fa82e562612815 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-73276",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:55:23.919951Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:55:30.190Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"vendor": "Erlang",
"versions": [
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "22.2",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "7.1.2",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "60add5a19e2154560fdff3fe92dba14a68bbd683",
"status": "unaffected"
},
{
"at": "6cd995e34d3bb3d36dd278dded2d62c25e71820c",
"status": "unaffected"
},
{
"at": "c285240c6e4b93960c5dc4f17ba04e6fdfb27a0f",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "c06db0bedf49a9b40725745e73fa82e562612815",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"versionStartIncluding": "22.2",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
},
{
"lang": "en",
"type": "reporter",
"value": "Lukas Backstr\u00f6m / Erlang Solutions"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eGracefulness code ignored cases that should be rejected, resulting in possible HTTP Request Smuggling opportunities.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;22.2 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 7.1.2 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Gracefulness code ignored cases that should be rejected, resulting in possible HTTP Request Smuggling opportunities.\n\nThis issue affects OTP from OTP\u00a022.2 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 7.1.2 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2."
}
],
"value": "Gracefulness code ignored cases that should be rejected, resulting in possible HTTP Request Smuggling opportunities.\n\nThis issue affects OTP from OTP\u00a022.2 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 7.1.2 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2."
}
],
"impacts": [
{
"capecId": "CAPEC-33",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-33 HTTP Request Smuggling"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.3,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:H/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "LOW",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-444",
"description": "CWE-444 Inconsistent Interpretation of HTTP Requests (\u0027HTTP Request/Response Smuggling\u0027)",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:10:02.081Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-6v7q-jwgh-cx8p"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-73276.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-73276"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/60add5a19e2154560fdff3fe92dba14a68bbd683"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/6cd995e34d3bb3d36dd278dded2d62c25e71820c"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/c285240c6e4b93960c5dc4f17ba04e6fdfb27a0f"
}
],
"source": {
"discovery": "UNKNOWN"
},
"title": "inets, httpd: HTTP Request Smuggling via Whitespace-Before-Colon Header Dropping i"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-73276",
"datePublished": "2026-09-01T14:41:24.565Z",
"dateReserved": "2026-08-12T20:00:01.107Z",
"dateUpdated": "2026-09-08T01:10:02.081Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-73270 (GCVE-0-2026-73270)
Vulnerability from nvd – Published: 2026-09-01 14:48 – Updated: 2026-09-08 01:09
VLAI
EPSS
VEX
Title
httpd mod_auth directory protection bypassed by request path casing on case-insensitive filesystems
Summary
Improper Handling of Case Sensitivity vulnerability in Erlang/OTP inets httpd allows a remote unauthenticated attacker to read files inside a mod_auth protected directory by requesting them with different casing, on deployments whose filesystem is case-insensitive.
mod_auth:secret_path/3 decides whether a resolved filesystem path lies inside a protected directory block by running the configured directory path through re:run/3 without the caseless option. A request for /secret/file against a directory configured as /Secret therefore does not match, so the request is treated as unprotected and no authentication challenge is issued, while the filesystem resolves the differently cased path to the same file and mod_get serves it. Deployments on case-sensitive filesystems are unaffected, because there the filesystem itself rejects the mismatched casing.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP 17.0, corresponding to inets before 5.10, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:58 UTC
CWE
- CWE-178 - Improper Handling of Case Sensitivity
Assigner
References
7 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-73270.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-73270 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/bac19eb3dbd9… | patch |
| https://github.com/erlang/otp/commit/d8878dec0ece… | patch |
| https://github.com/erlang/otp/commit/9641944a2efb… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 5.10
(otp)
Affected: 5.10 , < 9.3.2.7 (otp) Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-73270",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:58:36.382951Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:58:41.808Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"mod_auth"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_server/mod_auth.erl"
],
"programRoutines": [
{
"name": "mod_auth:secret_path/3"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"mod_auth"
],
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"programFiles": [
"src/http_server/mod_auth.erl"
],
"programRoutines": [
{
"name": "mod_auth:secret_path/3"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "5.10",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "5.10",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"mod_auth"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_server/mod_auth.erl"
],
"programRoutines": [
{
"name": "mod_auth:secret_path/3"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "bac19eb3dbd96cc49b6d8cabc1c04248bf8c79f6",
"status": "unaffected"
},
{
"at": "d8878dec0ececc2eab18e47bb18b472f224ca633",
"status": "unaffected"
},
{
"at": "9641944a2efbf55bea760f8ff7ba777fe3a0961c",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eTwo conditions must both hold. The server must protect a directory with \u003ccode\u003emod_auth\u003c/code\u003e, by configuring a \u003ccode\u003edirectory\u003c/code\u003e block with authentication requirements, and the document root must sit where the operating system resolves paths case-insensitively, which is the default on Windows and on macOS. Deployments whose path resolution is case-sensitive are unaffected.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Two conditions must both hold. The server must protect a directory with `mod_auth`, by configuring a `directory` block with authentication requirements, and the document root must sit where the operating system resolves paths case-insensitively, which is the default on Windows and on macOS. Deployments whose path resolution is case-sensitive are unaffected."
}
],
"value": "Two conditions must both hold. The server must protect a directory with mod_auth, by configuring a directory block with authentication requirements, and the document root must sit where the operating system resolves paths case-insensitively, which is the default on Windows and on macOS. Deployments whose path resolution is case-sensitive are unaffected."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
},
{
"lang": "en",
"type": "analyst",
"value": "Lukas Backstr\u00f6m / Erlang Solutions"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Handling of Case Sensitivity vulnerability in Erlang/OTP inets httpd allows a remote unauthenticated attacker to read files inside a \u003ccode\u003emod_auth\u003c/code\u003e protected directory by requesting them with different casing, on deployments whose filesystem is case-insensitive.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003emod_auth:secret_path/3\u003c/code\u003e decides whether a resolved filesystem path lies inside a protected \u003ccode\u003edirectory\u003c/code\u003e block by running the configured directory path through \u003ccode\u003ere:run/3\u003c/code\u003e without the \u003ccode\u003ecaseless\u003c/code\u003e option. A request for \u003ccode\u003e/secret/file\u003c/code\u003e against a directory configured as \u003ccode\u003e/Secret\u003c/code\u003e therefore does not match, so the request is treated as unprotected and no authentication challenge is issued, while the filesystem resolves the differently cased path to the same file and \u003ccode\u003emod_get\u003c/code\u003e serves it. Deployments on case-sensitive filesystems are unaffected, because there the filesystem itself rejects the mismatched casing.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u0026nbsp;17.0, corresponding to inets before 5.10, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Handling of Case Sensitivity vulnerability in Erlang/OTP inets httpd allows a remote unauthenticated attacker to read files inside a `mod_auth` protected directory by requesting them with different casing, on deployments whose filesystem is case-insensitive.\n\n`mod_auth:secret_path/3` decides whether a resolved filesystem path lies inside a protected `directory` block by running the configured directory path through `re:run/3` without the `caseless` option. A request for `/secret/file` against a directory configured as `/Secret` therefore does not match, so the request is treated as unprotected and no authentication challenge is issued, while the filesystem resolves the differently cased path to the same file and `mod_get` serves it. Deployments on case-sensitive filesystems are unaffected, because there the filesystem itself rejects the mismatched casing.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"value": "Improper Handling of Case Sensitivity vulnerability in Erlang/OTP inets httpd allows a remote unauthenticated attacker to read files inside a mod_auth protected directory by requesting them with different casing, on deployments whose filesystem is case-insensitive.\n\nmod_auth:secret_path/3 decides whether a resolved filesystem path lies inside a protected directory block by running the configured directory path through re:run/3 without the caseless option. A request for /secret/file against a directory configured as /Secret therefore does not match, so the request is treated as unprotected and no authentication challenge is issued, while the filesystem resolves the differently cased path to the same file and mod_get serves it. Deployments on case-sensitive filesystems are unaffected, because there the filesystem itself rejects the mismatched casing.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-76",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-76 Manipulating Web Input to File System Calls"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.2,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-178",
"description": "CWE-178 Improper Handling of Case Sensitivity",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:09:49.755Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-mh78-93cr-jx8f"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-73270.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-73270"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/bac19eb3dbd96cc49b6d8cabc1c04248bf8c79f6"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/d8878dec0ececc2eab18e47bb18b472f224ca633"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/9641944a2efbf55bea760f8ff7ba777fe3a0961c"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "httpd mod_auth directory protection bypassed by request path casing on case-insensitive filesystems",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cul\u003e\n\u003cli\u003eHost the document root on a case-sensitive filesystem, where the mismatched casing does not resolve to the protected file.\u003c/li\u003e\n\u003cli\u003ePlace a reverse proxy in front of httpd that performs its own case-insensitive path matching for the protected paths, or that normalises request path casing before forwarding.\u003c/li\u003e\n\u003cli\u003eRestrict access to the server to trusted clients where the deployment allows it.\u003c/li\u003e\n\u003c/ul\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "* Host the document root on a case-sensitive filesystem, where the mismatched casing does not resolve to the protected file.\n* Place a reverse proxy in front of httpd that performs its own case-insensitive path matching for the protected paths, or that normalises request path casing before forwarding.\n* Restrict access to the server to trusted clients where the deployment allows it."
}
],
"value": "* Host the document root on a case-sensitive filesystem, where the mismatched casing does not resolve to the protected file.\n* Place a reverse proxy in front of httpd that performs its own case-insensitive path matching for the protected paths, or that normalises request path casing before forwarding.\n* Restrict access to the server to trusted clients where the deployment allows it."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-73270",
"datePublished": "2026-09-01T14:48:53.200Z",
"dateReserved": "2026-08-17T11:15:02.315Z",
"dateUpdated": "2026-09-08T01:09:49.755Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-71562 (GCVE-0-2026-71562)
Vulnerability from nvd – Published: 2026-09-01 14:33 – Updated: 2026-09-08 01:09
VLAI
EPSS
VEX
Title
httpc does not bound server-supplied numeric header values before integer conversion
Summary
Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP inets httpc allows a malicious or compromised HTTP server to degrade availability by returning a numeric header whose value is a very long run of digits.
httpc_handler.erl converts the server-supplied Content-Length with list_to_integer/1 before comparing it against max_body_size, so the size check cannot protect the conversion, and the option defaults to nolimit in any case. The same unbounded conversion appears in httpc_response:format_response/1 for Content-Length and in httpc_response:get_ms_from_retry_after/1 for Retry-After, which is guarded only by a check that the first character is a digit. A value of up to roughly 1.26 million digits converts successfully and costs the requesting process hundreds of milliseconds of arbitrary-precision arithmetic per response. The conversion function is documented to accept integers of any size, so bounding the input is the caller's responsibility.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP 17.0, corresponding to inets before 5.10, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:53 UTC
CWE
- CWE-1284 - Improper Validation of Specified Quantity in Input
Assigner
References
6 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-71562.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-71562 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/aba0fe8c2d70… | patch |
| https://github.com/erlang/otp/commit/e3be1cfe9f6c… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 5.10
(otp)
Affected: 5.10 , < 9.3.2.7 (otp) Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-71562",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:53:17.483996Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:53:23.666Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpc_handler",
"httpc_response"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_client/httpc_handler.erl",
"lib/inets/src/http_client/httpc_response.erl"
],
"programRoutines": [
{
"name": "httpc_handler:handle_http_body/2"
},
{
"name": "httpc_response:format_response/1"
},
{
"name": "httpc_response:get_ms_from_retry_after/1"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpc_handler",
"httpc_response"
],
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"programFiles": [
"src/http_client/httpc_handler.erl",
"src/http_client/httpc_response.erl"
],
"programRoutines": [
{
"name": "httpc_handler:handle_http_body/2"
},
{
"name": "httpc_response:format_response/1"
},
{
"name": "httpc_response:get_ms_from_retry_after/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "5.10",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "5.10",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpc_handler",
"httpc_response"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_client/httpc_handler.erl",
"lib/inets/src/http_client/httpc_response.erl"
],
"programRoutines": [
{
"name": "httpc_handler:handle_http_body/2"
},
{
"name": "httpc_response:format_response/1"
},
{
"name": "httpc_response:get_ms_from_retry_after/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d",
"status": "unaffected"
},
{
"at": "e3be1cfe9f6cedd0cd20d9905e05601dfb31c8aa",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Eric Meadows-J\u00f6nsson"
},
{
"lang": "en",
"type": "finder",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "finder",
"value": "Jos\u00e9 Valim"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Validation of Specified Quantity in Input vulnerability in Erlang/OTP inets httpc allows a malicious or compromised HTTP server to degrade availability by returning a numeric header whose value is a very long run of digits.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ehttpc_handler.erl\u003c/code\u003e converts the server-supplied \u003ccode\u003eContent-Length\u003c/code\u003e with \u003ccode\u003elist_to_integer/1\u003c/code\u003e before comparing it against \u003ccode\u003emax_body_size\u003c/code\u003e, so the size check cannot protect the conversion, and the option defaults to \u003ccode\u003enolimit\u003c/code\u003e in any case. The same unbounded conversion appears in \u003ccode\u003ehttpc_response:format_response/1\u003c/code\u003e for \u003ccode\u003eContent-Length\u003c/code\u003e and in \u003ccode\u003ehttpc_response:get_ms_from_retry_after/1\u003c/code\u003e for \u003ccode\u003eRetry-After\u003c/code\u003e, which is guarded only by a check that the first character is a digit. A value of up to roughly 1.26 million digits converts successfully and costs the requesting process hundreds of milliseconds of arbitrary-precision arithmetic per response. The conversion function is documented to accept integers of any size, so bounding the input is the caller\u0027s responsibility.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u0026nbsp;17.0, corresponding to inets before 5.10, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP inets httpc allows a malicious or compromised HTTP server to degrade availability by returning a numeric header whose value is a very long run of digits.\n\n`httpc_handler.erl` converts the server-supplied `Content-Length` with `list_to_integer/1` before comparing it against `max_body_size`, so the size check cannot protect the conversion, and the option defaults to `nolimit` in any case. The same unbounded conversion appears in `httpc_response:format_response/1` for `Content-Length` and in `httpc_response:get_ms_from_retry_after/1` for `Retry-After`, which is guarded only by a check that the first character is a digit. A value of up to roughly 1.26 million digits converts successfully and costs the requesting process hundreds of milliseconds of arbitrary-precision arithmetic per response. The conversion function is documented to accept integers of any size, so bounding the input is the caller\u0027s responsibility.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"value": "Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP inets httpc allows a malicious or compromised HTTP server to degrade availability by returning a numeric header whose value is a very long run of digits.\n\nhttpc_handler.erl converts the server-supplied Content-Length with list_to_integer/1 before comparing it against max_body_size, so the size check cannot protect the conversion, and the option defaults to nolimit in any case. The same unbounded conversion appears in httpc_response:format_response/1 for Content-Length and in httpc_response:get_ms_from_retry_after/1 for Retry-After, which is guarded only by a check that the first character is a digit. A value of up to roughly 1.26 million digits converts successfully and costs the requesting process hundreds of milliseconds of arbitrary-precision arithmetic per response. The conversion function is documented to accept integers of any size, so bounding the input is the caller\u0027s responsibility.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-231",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-231 Oversized Serialized Data Payloads"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "LOW",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-1284",
"description": "CWE-1284 Improper Validation of Specified Quantity in Input",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:09:37.049Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-cqx9-9hq6-m8wf"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-71562.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-71562"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/e3be1cfe9f6cedd0cd20d9905e05601dfb31c8aa"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "httpc does not bound server-supplied numeric header values before integer conversion"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-71562",
"datePublished": "2026-09-01T14:33:41.833Z",
"dateReserved": "2026-08-07T15:15:01.474Z",
"dateUpdated": "2026-09-08T01:09:37.049Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-71380 (GCVE-0-2026-71380)
Vulnerability from nvd – Published: 2026-09-01 14:35 – Updated: 2026-09-08 01:09
VLAI
EPSS
VEX
Title
httpd applies no timeout while receiving a request body, parking a worker on a stalled client
Summary
Missing Release of Resource after Effective Lifetime vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by sending valid request headers with a large Content-Length and then stalling before the body is complete.
httpd_request_handler:handle_info/2 cancels the request timeout as soon as a parse step succeeds, which includes the headers, and the clause that handles a decoder asking for more data re-arms the socket with {active, once} without setting any further timer. httpd_request:whole_body/2 returns such a continuation whenever the bytes received are fewer than the announced Content-Length, so a well-formed request that stops mid-body leaves the worker waiting indefinitely. The periodic byte-rate check that would reclaim it is armed only when minimum_bytes_per_second is configured, which it is not by default. Repeating this across connections occupies every worker permitted by max_clients and denies service to legitimate clients at negligible bandwidth cost.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP 17.0, corresponding to inets before 5.10, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:52 UTC
CWE
- CWE-772 - Missing Release of Resource after Effective Lifetime
Assigner
References
5 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-71380.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-71380 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/81b453aac5a0… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 5.10
(otp)
Affected: 5.10 , < 9.3.2.7 (otp) Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < 81b453aac5a006bb8d26405f2bc3cf24e9d7733c
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-71380",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:52:01.904809Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:52:08.684Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpd_request_handler",
"httpd_request"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_server/httpd_request_handler.erl",
"lib/inets/src/http_server/httpd_request.erl"
],
"programRoutines": [
{
"name": "httpd_request_handler:handle_info/2"
},
{
"name": "httpd_request_handler:cancel_request_timeout/1"
},
{
"name": "httpd_request:whole_body/2"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpd_request_handler",
"httpd_request"
],
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"programFiles": [
"src/http_server/httpd_request_handler.erl",
"src/http_server/httpd_request.erl"
],
"programRoutines": [
{
"name": "httpd_request_handler:handle_info/2"
},
{
"name": "httpd_request_handler:cancel_request_timeout/1"
},
{
"name": "httpd_request:whole_body/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "5.10",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "5.10",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpd_request_handler",
"httpd_request"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_server/httpd_request_handler.erl",
"lib/inets/src/http_server/httpd_request.erl"
],
"programRoutines": [
{
"name": "httpd_request_handler:handle_info/2"
},
{
"name": "httpd_request_handler:cancel_request_timeout/1"
},
{
"name": "httpd_request:whole_body/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "81b453aac5a006bb8d26405f2bc3cf24e9d7733c",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
},
{
"lang": "en",
"type": "analyst",
"value": "Lukas Backstr\u00f6m / Erlang Solutions"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eMissing Release of Resource after Effective Lifetime vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by sending valid request headers with a large \u003ccode\u003eContent-Length\u003c/code\u003e and then stalling before the body is complete.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ehttpd_request_handler:handle_info/2\u003c/code\u003e cancels the request timeout as soon as a parse step succeeds, which includes the headers, and the clause that handles a decoder asking for more data re-arms the socket with \u003ccode\u003e{active, once}\u003c/code\u003e without setting any further timer. \u003ccode\u003ehttpd_request:whole_body/2\u003c/code\u003e returns such a continuation whenever the bytes received are fewer than the announced \u003ccode\u003eContent-Length\u003c/code\u003e, so a well-formed request that stops mid-body leaves the worker waiting indefinitely. The periodic byte-rate check that would reclaim it is armed only when \u003ccode\u003eminimum_bytes_per_second\u003c/code\u003e is configured, which it is not by default. Repeating this across connections occupies every worker permitted by \u003ccode\u003emax_clients\u003c/code\u003e and denies service to legitimate clients at negligible bandwidth cost.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u0026nbsp;17.0, corresponding to inets before 5.10, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Missing Release of Resource after Effective Lifetime vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by sending valid request headers with a large `Content-Length` and then stalling before the body is complete.\n\n`httpd_request_handler:handle_info/2` cancels the request timeout as soon as a parse step succeeds, which includes the headers, and the clause that handles a decoder asking for more data re-arms the socket with `{active, once}` without setting any further timer. `httpd_request:whole_body/2` returns such a continuation whenever the bytes received are fewer than the announced `Content-Length`, so a well-formed request that stops mid-body leaves the worker waiting indefinitely. The periodic byte-rate check that would reclaim it is armed only when `minimum_bytes_per_second` is configured, which it is not by default. Repeating this across connections occupies every worker permitted by `max_clients` and denies service to legitimate clients at negligible bandwidth cost.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"value": "Missing Release of Resource after Effective Lifetime vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by sending valid request headers with a large Content-Length and then stalling before the body is complete.\n\nhttpd_request_handler:handle_info/2 cancels the request timeout as soon as a parse step succeeds, which includes the headers, and the clause that handles a decoder asking for more data re-arms the socket with {active, once} without setting any further timer. httpd_request:whole_body/2 returns such a continuation whenever the bytes received are fewer than the announced Content-Length, so a well-formed request that stops mid-body leaves the worker waiting indefinitely. The periodic byte-rate check that would reclaim it is armed only when minimum_bytes_per_second is configured, which it is not by default. Repeating this across connections occupies every worker permitted by max_clients and denies service to legitimate clients at negligible bandwidth cost.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-469",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-469 HTTP DoS"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 8.7,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-772",
"description": "CWE-772 Missing Release of Resource after Effective Lifetime",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:09:23.481Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-5vp4-58hc-h8cc"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-71380.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-71380"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/81b453aac5a006bb8d26405f2bc3cf24e9d7733c"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "httpd applies no timeout while receiving a request body, parking a worker on a stalled client",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cul\u003e\n\u003cli\u003eSet \u003ccode\u003eminimum_bytes_per_second\u003c/code\u003e in the httpd configuration, for example \u003ccode\u003e{minimum_bytes_per_second, 200}\u003c/code\u003e. This arms a periodic byte-rate check that terminates a connection which has stopped delivering data, reclaiming the parked worker. The check is disabled by default.\u003c/li\u003e\n\u003cli\u003ePlace a reverse proxy in front of httpd that enforces its own body-read timeout, such as \u003ccode\u003eclient_body_timeout\u003c/code\u003e in nginx.\u003c/li\u003e\n\u003cli\u003eRestrict access to the server to trusted clients where the deployment allows it.\u003c/li\u003e\n\u003c/ul\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "* Set `minimum_bytes_per_second` in the httpd configuration, for example `{minimum_bytes_per_second, 200}`. This arms a periodic byte-rate check that terminates a connection which has stopped delivering data, reclaiming the parked worker. The check is disabled by default.\n* Place a reverse proxy in front of httpd that enforces its own body-read timeout, such as `client_body_timeout` in nginx.\n* Restrict access to the server to trusted clients where the deployment allows it."
}
],
"value": "* Set minimum_bytes_per_second in the httpd configuration, for example {minimum_bytes_per_second, 200}. This arms a periodic byte-rate check that terminates a connection which has stopped delivering data, reclaiming the parked worker. The check is disabled by default.\n* Place a reverse proxy in front of httpd that enforces its own body-read timeout, such as client_body_timeout in nginx.\n* Restrict access to the server to trusted clients where the deployment allows it."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-71380",
"datePublished": "2026-09-01T14:35:31.192Z",
"dateReserved": "2026-08-17T12:45:01.757Z",
"dateUpdated": "2026-09-08T01:09:23.481Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-70409 (GCVE-0-2026-70409)
Vulnerability from nvd – Published: 2026-09-01 14:51 – Updated: 2026-09-08 01:09
VLAI
EPSS
VEX
Title
eldap does not bound the port component of a referral URL before integer conversion
Summary
Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP eldap allows a malicious or compromised LDAP server to degrade availability by returning a referral URL whose port component is a very long run of digits.
eldap:parse_port/2 passes the port substring straight to list_to_integer/1 with no length bound. The surrounding try ... catch only rejects a value that fails to parse, so a syntactically valid port of up to roughly 1.26 million digits converts successfully and costs the caller hundreds of milliseconds of arbitrary-precision arithmetic per referral. The conversion function itself is documented to accept integers of any size, so bounding the input is the caller's responsibility. Reaching the flaw requires the application to pass a server-supplied referral to eldap:parse_ldap_url/1, which eldap never calls itself: referral strings are returned to the caller unparsed.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to eldap from 1.0.3 before 1.2.14.2, from 1.2.15 before 1.2.16.1, and from 1.3 before 1.3.1.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 17:52 UTC
CWE
- CWE-1284 - Improper Validation of Specified Quantity in Input
Assigner
References
6 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-70409.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-70409 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/aba0fe8c2d70… | patch |
| https://github.com/erlang/otp/commit/e3be1cfe9f6c… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
17.0 , < 27.3.4.17
(otp)
Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
1.0.3 , < 1.2.14.2
(otp)
Affected: 1.2.15 , < 1.2.16.1 (otp) Affected: 1.3 , < 1.3.1 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
d8dbf15de4fa1a08b9a05e7d8e08fdb025fe1dc3 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-70409",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T17:52:58.419812Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T17:54:18.825Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"eldap"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/eldap/src/eldap.erl"
],
"programRoutines": [
{
"name": "eldap:parse_port/2"
},
{
"name": "eldap:parse_hostport/1"
},
{
"name": "eldap:parse_ldap_url/1"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"eldap"
],
"packageName": "eldap",
"packageURL": "pkg:otp/eldap",
"product": "OTP",
"programFiles": [
"src/eldap.erl"
],
"programRoutines": [
{
"name": "eldap:parse_port/2"
},
{
"name": "eldap:parse_hostport/1"
},
{
"name": "eldap:parse_ldap_url/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "1.2.14.2",
"status": "affected",
"version": "1.0.3",
"versionType": "otp"
},
{
"lessThan": "1.2.16.1",
"status": "affected",
"version": "1.2.15",
"versionType": "otp"
},
{
"lessThan": "1.3.1",
"status": "affected",
"version": "1.3",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"eldap"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/eldap/src/eldap.erl"
],
"programRoutines": [
{
"name": "eldap:parse_port/2"
},
{
"name": "eldap:parse_hostport/1"
},
{
"name": "eldap:parse_ldap_url/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d",
"status": "unaffected"
},
{
"at": "e3be1cfe9f6cedd0cd20d9905e05601dfb31c8aa",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "d8dbf15de4fa1a08b9a05e7d8e08fdb025fe1dc3",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"versionStartIncluding": "17.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Eric Meadows-J\u00f6nsson"
},
{
"lang": "en",
"type": "finder",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "finder",
"value": "Jos\u00e9 Valim"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Validation of Specified Quantity in Input vulnerability in Erlang/OTP eldap allows a malicious or compromised LDAP server to degrade availability by returning a referral URL whose port component is a very long run of digits.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eeldap:parse_port/2\u003c/code\u003e passes the port substring straight to \u003ccode\u003elist_to_integer/1\u003c/code\u003e with no length bound. The surrounding \u003ccode\u003etry ... catch\u003c/code\u003e only rejects a value that fails to parse, so a syntactically valid port of up to roughly 1.26 million digits converts successfully and costs the caller hundreds of milliseconds of arbitrary-precision arithmetic per referral. The conversion function itself is documented to accept integers of any size, so bounding the input is the caller\u0027s responsibility. Reaching the flaw requires the application to pass a server-supplied referral to \u003ccode\u003eeldap:parse_ldap_url/1\u003c/code\u003e, which eldap never calls itself: referral strings are returned to the caller unparsed.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to eldap from 1.0.3 before 1.2.14.2, from 1.2.15 before 1.2.16.1, and from 1.3 before 1.3.1.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP eldap allows a malicious or compromised LDAP server to degrade availability by returning a referral URL whose port component is a very long run of digits.\n\n`eldap:parse_port/2` passes the port substring straight to `list_to_integer/1` with no length bound. The surrounding `try ... catch` only rejects a value that fails to parse, so a syntactically valid port of up to roughly 1.26 million digits converts successfully and costs the caller hundreds of milliseconds of arbitrary-precision arithmetic per referral. The conversion function itself is documented to accept integers of any size, so bounding the input is the caller\u0027s responsibility. Reaching the flaw requires the application to pass a server-supplied referral to `eldap:parse_ldap_url/1`, which eldap never calls itself: referral strings are returned to the caller unparsed.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to eldap from 1.0.3 before 1.2.14.2, from 1.2.15 before 1.2.16.1, and from 1.3 before 1.3.1."
}
],
"value": "Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP eldap allows a malicious or compromised LDAP server to degrade availability by returning a referral URL whose port component is a very long run of digits.\n\neldap:parse_port/2 passes the port substring straight to list_to_integer/1 with no length bound. The surrounding try ... catch only rejects a value that fails to parse, so a syntactically valid port of up to roughly 1.26 million digits converts successfully and costs the caller hundreds of milliseconds of arbitrary-precision arithmetic per referral. The conversion function itself is documented to accept integers of any size, so bounding the input is the caller\u0027s responsibility. Reaching the flaw requires the application to pass a server-supplied referral to eldap:parse_ldap_url/1, which eldap never calls itself: referral strings are returned to the caller unparsed.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to eldap from 1.0.3 before 1.2.14.2, from 1.2.15 before 1.2.16.1, and from 1.3 before 1.3.1."
}
],
"impacts": [
{
"capecId": "CAPEC-231",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-231 Oversized Serialized Data Payloads"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "LOW",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-1284",
"description": "CWE-1284 Improper Validation of Specified Quantity in Input",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:09:09.018Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-9vgh-c8cm-m9p4"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-70409.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-70409"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/e3be1cfe9f6cedd0cd20d9905e05601dfb31c8aa"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "eldap does not bound the port component of a referral URL before integer conversion"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-70409",
"datePublished": "2026-09-01T14:51:00.770Z",
"dateReserved": "2026-08-09T16:30:01.576Z",
"dateUpdated": "2026-09-08T01:09:09.018Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-70405 (GCVE-0-2026-70405)
Vulnerability from nvd – Published: 2026-09-01 14:50 – Updated: 2026-09-08 01:08
VLAI
EPSS
VEX
Title
snmp BER INTEGER decoder applies no size limit to attacker-supplied integer fields
Summary
Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP snmp allows a remote attacker to degrade availability by sending an SNMP message containing a BER INTEGER whose length field is arbitrarily large.
snmp_pdus:dec_integer_notag/1 defaults its size limit to infinity, and do_dec_integer_notag/2 then accumulates the value across every declared byte with a recursive shift and bitwise or. Work grows superlinearly in the declared length because each operation acts on a progressively larger bignum. The size-limited variant dec_integer_notag/2 exists but is reached from only one call site, dec_snmp_version/1, which bounds the version field to ten bytes; the request identifier, error status and index, generic and specific trap fields, engine boots and time, and every varbind value decoded by dec_value/1 all use the unbounded form. The decode runs before the PDU is processed, so no valid request is required beyond what the deployment demands to accept the message at all.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to snmp from 4.25.1 before 5.18.2.1, from 5.19 before 5.20.2.2, and from 5.20.3 before 5.20.5. Whether OTP before OTP 17.0, corresponding to snmp before 4.25.1, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 18:09 UTC
CWE
- CWE-1284 - Improper Validation of Specified Quantity in Input
Assigner
References
6 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-70405.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-70405 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/aba0fe8c2d70… | patch |
| https://github.com/erlang/otp/commit/e3be1cfe9f6c… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 4.25.1
(otp)
Affected: 4.25.1 , < 5.18.2.1 (otp) Affected: 5.19 , < 5.20.2.2 (otp) Affected: 5.20.3 , < 5.20.5 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-70405",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T18:09:46.379754Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T18:10:13.162Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"snmp_pdus"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/snmp/src/misc/snmp_pdus.erl"
],
"programRoutines": [
{
"name": "snmp_pdus:dec_integer_notag/1"
},
{
"name": "snmp_pdus:do_dec_integer_notag/2"
},
{
"name": "snmp_pdus:dec_value/1"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"snmp_pdus"
],
"packageName": "snmp",
"packageURL": "pkg:otp/snmp",
"product": "OTP",
"programFiles": [
"src/misc/snmp_pdus.erl"
],
"programRoutines": [
{
"name": "snmp_pdus:dec_integer_notag/1"
},
{
"name": "snmp_pdus:do_dec_integer_notag/2"
},
{
"name": "snmp_pdus:dec_value/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "4.25.1",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "5.18.2.1",
"status": "affected",
"version": "4.25.1",
"versionType": "otp"
},
{
"lessThan": "5.20.2.2",
"status": "affected",
"version": "5.19",
"versionType": "otp"
},
{
"lessThan": "5.20.5",
"status": "affected",
"version": "5.20.3",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"snmp_pdus"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/snmp/src/misc/snmp_pdus.erl"
],
"programRoutines": [
{
"name": "snmp_pdus:dec_integer_notag/1"
},
{
"name": "snmp_pdus:do_dec_integer_notag/2"
},
{
"name": "snmp_pdus:dec_value/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d",
"status": "unaffected"
},
{
"at": "e3be1cfe9f6cedd0cd20d9905e05601dfb31c8aa",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Eric Meadows-J\u00f6nsson"
},
{
"lang": "en",
"type": "finder",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "finder",
"value": "Jos\u00e9 Valim"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Validation of Specified Quantity in Input vulnerability in Erlang/OTP snmp allows a remote attacker to degrade availability by sending an SNMP message containing a BER INTEGER whose length field is arbitrarily large.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003esnmp_pdus:dec_integer_notag/1\u003c/code\u003e defaults its size limit to \u003ccode\u003einfinity\u003c/code\u003e, and \u003ccode\u003edo_dec_integer_notag/2\u003c/code\u003e then accumulates the value across every declared byte with a recursive shift and bitwise or. Work grows superlinearly in the declared length because each operation acts on a progressively larger bignum. The size-limited variant \u003ccode\u003edec_integer_notag/2\u003c/code\u003e exists but is reached from only one call site, \u003ccode\u003edec_snmp_version/1\u003c/code\u003e, which bounds the version field to ten bytes; the request identifier, error status and index, generic and specific trap fields, engine boots and time, and every varbind value decoded by \u003ccode\u003edec_value/1\u003c/code\u003e all use the unbounded form. The decode runs before the PDU is processed, so no valid request is required beyond what the deployment demands to accept the message at all.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to snmp from 4.25.1 before 5.18.2.1, from 5.19 before 5.20.2.2, and from 5.20.3 before 5.20.5. Whether OTP before OTP\u0026nbsp;17.0, corresponding to snmp before 4.25.1, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP snmp allows a remote attacker to degrade availability by sending an SNMP message containing a BER INTEGER whose length field is arbitrarily large.\n\n`snmp_pdus:dec_integer_notag/1` defaults its size limit to `infinity`, and `do_dec_integer_notag/2` then accumulates the value across every declared byte with a recursive shift and bitwise or. Work grows superlinearly in the declared length because each operation acts on a progressively larger bignum. The size-limited variant `dec_integer_notag/2` exists but is reached from only one call site, `dec_snmp_version/1`, which bounds the version field to ten bytes; the request identifier, error status and index, generic and specific trap fields, engine boots and time, and every varbind value decoded by `dec_value/1` all use the unbounded form. The decode runs before the PDU is processed, so no valid request is required beyond what the deployment demands to accept the message at all.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to snmp from 4.25.1 before 5.18.2.1, from 5.19 before 5.20.2.2, and from 5.20.3 before 5.20.5. Whether OTP before OTP\u00a017.0, corresponding to snmp before 4.25.1, is affected is unknown."
}
],
"value": "Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP snmp allows a remote attacker to degrade availability by sending an SNMP message containing a BER INTEGER whose length field is arbitrarily large.\n\nsnmp_pdus:dec_integer_notag/1 defaults its size limit to infinity, and do_dec_integer_notag/2 then accumulates the value across every declared byte with a recursive shift and bitwise or. Work grows superlinearly in the declared length because each operation acts on a progressively larger bignum. The size-limited variant dec_integer_notag/2 exists but is reached from only one call site, dec_snmp_version/1, which bounds the version field to ten bytes; the request identifier, error status and index, generic and specific trap fields, engine boots and time, and every varbind value decoded by dec_value/1 all use the unbounded form. The decode runs before the PDU is processed, so no valid request is required beyond what the deployment demands to accept the message at all.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to snmp from 4.25.1 before 5.18.2.1, from 5.19 before 5.20.2.2, and from 5.20.3 before 5.20.5. Whether OTP before OTP\u00a017.0, corresponding to snmp before 4.25.1, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-231",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-231 Oversized Serialized Data Payloads"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 6.3,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "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",
"version": "4.0",
"vulnAvailabilityImpact": "LOW",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-1284",
"description": "CWE-1284 Improper Validation of Specified Quantity in Input",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:08:55.059Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-q7cq-pfgf-5hr7"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-70405.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-70405"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/e3be1cfe9f6cedd0cd20d9905e05601dfb31c8aa"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "snmp BER INTEGER decoder applies no size limit to attacker-supplied integer fields"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-70405",
"datePublished": "2026-09-01T14:50:34.263Z",
"dateReserved": "2026-08-06T11:45:02.140Z",
"dateUpdated": "2026-09-08T01:08:55.059Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-70399 (GCVE-0-2026-70399)
Vulnerability from nvd – Published: 2026-09-01 14:33 – Updated: 2026-09-08 01:08
VLAI
EPSS
VEX
Title
httpd does not enforce the documented default max_clients connection limit
Summary
Allocation of Resources Without Limits or Throttling vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by opening and holding open a large number of connections. The max_clients option is documented to default to 150, and the inets hardening guide presents that limit as the first layer of denial-of-service defence, but a server that does not set it explicitly accepts an unlimited number of simultaneous connections. Establishing the connections is sufficient; no valid request and no authentication are required.
The accept gate in httpd_manager:handle_new_connection/4 reads the option with httpd_util:lookup/2, which returns undefined when the key is absent, rather than the three-argument form carrying the 150 default that the neighbouring get_ustate/2 uses. Erlang term ordering places every integer before every atom, so the Count =< Max guard holds for any connection count and the server never returns {reject, busy}. Each accepted connection occupies a worker process and a socket for as long as it is held, driving the node towards process, memory and file descriptor exhaustion. Servers that set max_clients explicitly are unaffected, because a configured value is applied as intended.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:52 UTC
CWE
- CWE-770 - Allocation of Resources Without Limits or Throttling
Assigner
References
7 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-70399.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-70399 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/d94a94c96eb4… | patch |
| https://github.com/erlang/otp/commit/6746dc4e1df5… | patch |
| https://github.com/erlang/otp/commit/e0050fc00c50… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
17.0 , < 27.3.4.17
(otp)
Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
5.10 , < 9.3.2.7
(otp)
Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
d9674f32811cd5bb02b0d6656053b5ee226bc74c , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-70399",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:52:45.671034Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:52:53.186Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpd_manager"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_server/httpd_manager.erl"
],
"programRoutines": [
{
"name": "httpd_manager:handle_new_connection/4"
},
{
"name": "httpd_manager:new_connection/1"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpd_manager"
],
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"programFiles": [
"src/http_server/httpd_manager.erl"
],
"programRoutines": [
{
"name": "httpd_manager:handle_new_connection/4"
},
{
"name": "httpd_manager:new_connection/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "5.10",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpd_manager"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_server/httpd_manager.erl"
],
"programRoutines": [
{
"name": "httpd_manager:handle_new_connection/4"
},
{
"name": "httpd_manager:new_connection/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "d94a94c96eb4cccbd6f7d7da5975f0c035b69612",
"status": "unaffected"
},
{
"at": "6746dc4e1df5257ad8ac91cbbd167cb8b0274ce7",
"status": "unaffected"
},
{
"at": "e0050fc00c500a4fa9ba1f594603c787ff6d20b2",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "d9674f32811cd5bb02b0d6656053b5ee226bc74c",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eOnly servers that do not set \u003ccode\u003emax_clients\u003c/code\u003e in the httpd configuration are affected. A server that sets the option to any integer value applies the limit as intended.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Only servers that do not set `max_clients` in the httpd configuration are affected. A server that sets the option to any integer value applies the limit as intended."
}
],
"value": "Only servers that do not set max_clients in the httpd configuration are affected. A server that sets the option to any integer value applies the limit as intended."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"versionStartIncluding": "17.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Lukas Backstr\u00f6m / Erlang Solutions"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Lukas Backstr\u00f6m / Erlang Solutions"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Konrad Pietrzak / Ericsson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAllocation of Resources Without Limits or Throttling vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by opening and holding open a large number of connections. The \u003ccode\u003emax_clients\u003c/code\u003e option is documented to default to \u003ccode\u003e150\u003c/code\u003e, and the inets hardening guide presents that limit as the first layer of denial-of-service defence, but a server that does not set it explicitly accepts an unlimited number of simultaneous connections. Establishing the connections is sufficient; no valid request and no authentication are required.\u003c/p\u003e\n\u003cp\u003eThe accept gate in \u003ccode\u003ehttpd_manager:handle_new_connection/4\u003c/code\u003e reads the option with \u003ccode\u003ehttpd_util:lookup/2\u003c/code\u003e, which returns \u003ccode\u003eundefined\u003c/code\u003e when the key is absent, rather than the three-argument form carrying the \u003ccode\u003e150\u003c/code\u003e default that the neighbouring \u003ccode\u003eget_ustate/2\u003c/code\u003e uses. Erlang term ordering places every integer before every atom, so the \u003ccode\u003eCount =\u0026lt; Max\u003c/code\u003e guard holds for any connection count and the server never returns \u003ccode\u003e{reject, busy}\u003c/code\u003e. Each accepted connection occupies a worker process and a socket for as long as it is held, driving the node towards process, memory and file descriptor exhaustion. Servers that set \u003ccode\u003emax_clients\u003c/code\u003e explicitly are unaffected, because a configured value is applied as intended.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Allocation of Resources Without Limits or Throttling vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by opening and holding open a large number of connections. The `max_clients` option is documented to default to `150`, and the inets hardening guide presents that limit as the first layer of denial-of-service defence, but a server that does not set it explicitly accepts an unlimited number of simultaneous connections. Establishing the connections is sufficient; no valid request and no authentication are required.\n\nThe accept gate in `httpd_manager:handle_new_connection/4` reads the option with `httpd_util:lookup/2`, which returns `undefined` when the key is absent, rather than the three-argument form carrying the `150` default that the neighbouring `get_ustate/2` uses. Erlang term ordering places every integer before every atom, so the `Count =\u003c Max` guard holds for any connection count and the server never returns `{reject, busy}`. Each accepted connection occupies a worker process and a socket for as long as it is held, driving the node towards process, memory and file descriptor exhaustion. Servers that set `max_clients` explicitly are unaffected, because a configured value is applied as intended.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2."
}
],
"value": "Allocation of Resources Without Limits or Throttling vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by opening and holding open a large number of connections. The max_clients option is documented to default to 150, and the inets hardening guide presents that limit as the first layer of denial-of-service defence, but a server that does not set it explicitly accepts an unlimited number of simultaneous connections. Establishing the connections is sufficient; no valid request and no authentication are required.\n\nThe accept gate in httpd_manager:handle_new_connection/4 reads the option with httpd_util:lookup/2, which returns undefined when the key is absent, rather than the three-argument form carrying the 150 default that the neighbouring get_ustate/2 uses. Erlang term ordering places every integer before every atom, so the Count =\u003c Max guard holds for any connection count and the server never returns {reject, busy}. Each accepted connection occupies a worker process and a socket for as long as it is held, driving the node towards process, memory and file descriptor exhaustion. Servers that set max_clients explicitly are unaffected, because a configured value is applied as intended.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2."
}
],
"impacts": [
{
"capecId": "CAPEC-469",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-469 HTTP DoS"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 8.7,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-770",
"description": "CWE-770 Allocation of Resources Without Limits or Throttling",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:08:41.997Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-pwvh-c689-f8q5"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-70399.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-70399"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/d94a94c96eb4cccbd6f7d7da5975f0c035b69612"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/6746dc4e1df5257ad8ac91cbbd167cb8b0274ce7"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/e0050fc00c500a4fa9ba1f594603c787ff6d20b2"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "httpd does not enforce the documented default max_clients connection limit",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cul\u003e\n\u003cli\u003eSet \u003ccode\u003emax_clients\u003c/code\u003e explicitly in the httpd configuration, for example \u003ccode\u003e{max_clients, 150}\u003c/code\u003e. An explicitly configured value is read by the same accept gate and applied as intended, so this restores the documented limit without upgrading.\u003c/li\u003e\n\u003cli\u003eLimit concurrent connections in front of httpd, for example with reverse proxy or firewall connection-count and connection-rate rules.\u003c/li\u003e\n\u003cli\u003eRestrict access to the server to trusted clients where the deployment allows it.\u003c/li\u003e\n\u003c/ul\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "* Set `max_clients` explicitly in the httpd configuration, for example `{max_clients, 150}`. An explicitly configured value is read by the same accept gate and applied as intended, so this restores the documented limit without upgrading.\n* Limit concurrent connections in front of httpd, for example with reverse proxy or firewall connection-count and connection-rate rules.\n* Restrict access to the server to trusted clients where the deployment allows it."
}
],
"value": "* Set max_clients explicitly in the httpd configuration, for example {max_clients, 150}. An explicitly configured value is read by the same accept gate and applied as intended, so this restores the documented limit without upgrading.\n* Limit concurrent connections in front of httpd, for example with reverse proxy or firewall connection-count and connection-rate rules.\n* Restrict access to the server to trusted clients where the deployment allows it."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-70399",
"datePublished": "2026-09-01T14:33:05.717Z",
"dateReserved": "2026-08-06T13:00:02.045Z",
"dateUpdated": "2026-09-08T01:08:41.997Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-69664 (GCVE-0-2026-69664)
Vulnerability from nvd – Published: 2026-09-01 14:59 – Updated: 2026-09-22 09:10
VLAI
EPSS
VEX
Title
httpd parks a request worker indefinitely on a malformed chunk size sent after the headers
Summary
Missing Release of Resource after Effective Lifetime vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by sending a request with a chunked body whose chunk-size line is not a hexadecimal number. The worker serving the connection is never released and no timeout reclaims it, so repeating the request across connections occupies every available worker and denies service to legitimate clients. No authentication is required and the default configuration is affected.
The chunk-size line must arrive in a write separate from the headers. When the body accompanies the headers, httpd_request_handler:handle_body/3 calls http_chunk:decode/3 inside a try ... catch throw:Error, so the {error, {chunk_size, _}} thrown by http_chunk:decode_size/4 is answered with 400 Bad Request. When the chunk size arrives later, the decoder is resumed through a bare catch in httpd_request_handler:handle_info/2, which converts the throw into a return value rather than raising it; the resulting error tuple is then treated as the next decoder continuation, the socket is re-armed, and the worker waits for data that never comes. The request timeout has already been cancelled at the point the headers were accepted, and the periodic byte-rate check is only armed when minimum_bytes_per_second is configured, which it is not by default.
This issue affects OTP from OTP 18.1.4 before OTP 27.3.4.17, OTP 28.5.0.6, and OTP 29.0.6, corresponding to inets from 6.0.3 before 9.3.2.7, 9.6.2.3, and 9.7.2.
Severity
SSVC
Exploitation: poc
Automatable: yes
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 17:44 UTC
CWE
- CWE-772 - Missing Release of Resource after Effective Lifetime
Assigner
References
8 references
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
18.1.4 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
6.0.3 , < *
(otp)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
77acb473d8f056f6f534395f131c6e45693797f0 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-69664",
"options": [
{
"Exploitation": "poc"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T17:44:51.976604Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T17:45:20.907Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"references": [
{
"tags": [
"exploit"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-mr35-8h7w-w3gq"
}
],
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"http_chunk",
"httpd_request_handler"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_lib/http_chunk.erl",
"lib/inets/src/http_server/httpd_request_handler.erl"
],
"programRoutines": [
{
"name": "http_chunk:decode_size/4"
},
{
"name": "httpd_request_handler:handle_info/2"
},
{
"name": "httpd_request_handler:handle_body/3"
}
],
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "27.3.4.17",
"status": "unaffected"
},
{
"at": "28.5.0.6",
"status": "unaffected"
},
{
"at": "29.0.6",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "18.1.4",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"http_chunk",
"httpd_request_handler"
],
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"programFiles": [
"src/http_lib/http_chunk.erl",
"src/http_server/httpd_request_handler.erl"
],
"programRoutines": [
{
"name": "http_chunk:decode_size/4"
},
{
"name": "httpd_request_handler:handle_info/2"
},
{
"name": "httpd_request_handler:handle_body/3"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "9.3.2.7",
"status": "unaffected"
},
{
"at": "9.6.2.3",
"status": "unaffected"
},
{
"at": "9.7.2",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "6.0.3",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"http_chunk",
"httpd_request_handler"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_lib/http_chunk.erl",
"lib/inets/src/http_server/httpd_request_handler.erl"
],
"programRoutines": [
{
"name": "http_chunk:decode_size/4"
},
{
"name": "httpd_request_handler:handle_info/2"
},
{
"name": "httpd_request_handler:handle_body/3"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "a3adf63078438c86527d704e23282b7721d8ca12",
"status": "unaffected"
},
{
"at": "df1a9ca4666e2fdfc44886bfaae76de086d803f6",
"status": "unaffected"
},
{
"at": "bd4e74348c6be8a49f060da6fd48d43f3a960292",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "77acb473d8f056f6f534395f131c6e45693797f0",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"versionStartIncluding": "18.1.4",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Lukas Backstr\u00f6m"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Lukas Backstr\u00f6m"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Konrad Pietrzak / Ericsson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eMissing Release of Resource after Effective Lifetime vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by sending a request with a chunked body whose chunk-size line is not a hexadecimal number. The worker serving the connection is never released and no timeout reclaims it, so repeating the request across connections occupies every available worker and denies service to legitimate clients. No authentication is required and the default configuration is affected.\u003c/p\u003e\n\u003cp\u003eThe chunk-size line must arrive in a write separate from the headers. When the body accompanies the headers, \u003ccode\u003ehttpd_request_handler:handle_body/3\u003c/code\u003e calls \u003ccode\u003ehttp_chunk:decode/3\u003c/code\u003e inside a \u003ccode\u003etry ... catch throw:Error\u003c/code\u003e, so the \u003ccode\u003e{error, {chunk_size, _}}\u003c/code\u003e thrown by \u003ccode\u003ehttp_chunk:decode_size/4\u003c/code\u003e is answered with \u003ccode\u003e400 Bad Request\u003c/code\u003e. When the chunk size arrives later, the decoder is resumed through a bare \u003ccode\u003ecatch\u003c/code\u003e in \u003ccode\u003ehttpd_request_handler:handle_info/2\u003c/code\u003e, which converts the throw into a return value rather than raising it; the resulting error tuple is then treated as the next decoder continuation, the socket is re-armed, and the worker waits for data that never comes. The request timeout has already been cancelled at the point the headers were accepted, and the periodic byte-rate check is only armed when \u003ccode\u003eminimum_bytes_per_second\u003c/code\u003e is configured, which it is not by default.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;18.1.4 before OTP\u0026nbsp;27.3.4.17, OTP\u0026nbsp;28.5.0.6, and OTP\u0026nbsp;29.0.6, corresponding to inets from 6.0.3 before 9.3.2.7, 9.6.2.3, and 9.7.2.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Missing Release of Resource after Effective Lifetime vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by sending a request with a chunked body whose chunk-size line is not a hexadecimal number. The worker serving the connection is never released and no timeout reclaims it, so repeating the request across connections occupies every available worker and denies service to legitimate clients. No authentication is required and the default configuration is affected.\n\nThe chunk-size line must arrive in a write separate from the headers. When the body accompanies the headers, `httpd_request_handler:handle_body/3` calls `http_chunk:decode/3` inside a `try ... catch throw:Error`, so the `{error, {chunk_size, _}}` thrown by `http_chunk:decode_size/4` is answered with `400 Bad Request`. When the chunk size arrives later, the decoder is resumed through a bare `catch` in `httpd_request_handler:handle_info/2`, which converts the throw into a return value rather than raising it; the resulting error tuple is then treated as the next decoder continuation, the socket is re-armed, and the worker waits for data that never comes. The request timeout has already been cancelled at the point the headers were accepted, and the periodic byte-rate check is only armed when `minimum_bytes_per_second` is configured, which it is not by default.\n\nThis issue affects OTP from OTP\u00a018.1.4 before OTP\u00a027.3.4.17, OTP\u00a028.5.0.6, and OTP\u00a029.0.6, corresponding to inets from 6.0.3 before 9.3.2.7, 9.6.2.3, and 9.7.2."
}
],
"value": "Missing Release of Resource after Effective Lifetime vulnerability in Erlang/OTP inets httpd allows an unauthenticated remote attacker to cause denial of service by sending a request with a chunked body whose chunk-size line is not a hexadecimal number. The worker serving the connection is never released and no timeout reclaims it, so repeating the request across connections occupies every available worker and denies service to legitimate clients. No authentication is required and the default configuration is affected.\n\nThe chunk-size line must arrive in a write separate from the headers. When the body accompanies the headers, httpd_request_handler:handle_body/3 calls http_chunk:decode/3 inside a try ... catch throw:Error, so the {error, {chunk_size, _}} thrown by http_chunk:decode_size/4 is answered with 400 Bad Request. When the chunk size arrives later, the decoder is resumed through a bare catch in httpd_request_handler:handle_info/2, which converts the throw into a return value rather than raising it; the resulting error tuple is then treated as the next decoder continuation, the socket is re-armed, and the worker waits for data that never comes. The request timeout has already been cancelled at the point the headers were accepted, and the periodic byte-rate check is only armed when minimum_bytes_per_second is configured, which it is not by default.\n\nThis issue affects OTP from OTP\u00a018.1.4 before OTP\u00a027.3.4.17, OTP\u00a028.5.0.6, and OTP\u00a029.0.6, corresponding to inets from 6.0.3 before 9.3.2.7, 9.6.2.3, and 9.7.2."
}
],
"impacts": [
{
"capecId": "CAPEC-469",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-469 HTTP DoS"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 8.7,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-772",
"description": "CWE-772 Missing Release of Resource after Effective Lifetime",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-22T09:10:07.550Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"name": "GitHub Advisory",
"tags": [
"related",
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-mr35-8h7w-w3gq"
},
{
"name": "EEF CNA record for CVE-2026-69664",
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-69664.html"
},
{
"name": "OSV record EEF-CVE-2026-69664",
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-69664"
},
{
"name": "Erlang/OTP version ordering",
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"name": "Introducing commit 77acb47 in erlang/otp",
"tags": [
"related"
],
"url": "https://github.com/erlang/otp/commit/77acb473d8f056f6f534395f131c6e45693797f0"
},
{
"name": "Fix commit a3adf63 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/a3adf63078438c86527d704e23282b7721d8ca12"
},
{
"name": "Fix commit df1a9ca in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/df1a9ca4666e2fdfc44886bfaae76de086d803f6"
},
{
"name": "Fix commit bd4e743 in erlang/otp",
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/bd4e74348c6be8a49f060da6fd48d43f3a960292"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "httpd parks a request worker indefinitely on a malformed chunk size sent after the headers",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cul\u003e\n\u003cli\u003eSet \u003ccode\u003eminimum_bytes_per_second\u003c/code\u003e in the httpd configuration, for example \u003ccode\u003e{minimum_bytes_per_second, 200}\u003c/code\u003e. This arms a periodic byte-rate check that terminates a connection which has stopped delivering data, reclaiming the parked worker within a few seconds. The check is disabled by default, and any positive value suffices because an affected connection delivers no further data at all.\u003c/li\u003e\n\u003cli\u003ePlace a reverse proxy in front of httpd that validates chunked transfer encoding and rejects malformed chunk framing before it reaches httpd.\u003c/li\u003e\n\u003cli\u003eRestrict access to the server to trusted clients where the deployment allows it.\u003c/li\u003e\n\u003c/ul\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "* Set `minimum_bytes_per_second` in the httpd configuration, for example `{minimum_bytes_per_second, 200}`. This arms a periodic byte-rate check that terminates a connection which has stopped delivering data, reclaiming the parked worker within a few seconds. The check is disabled by default, and any positive value suffices because an affected connection delivers no further data at all.\n* Place a reverse proxy in front of httpd that validates chunked transfer encoding and rejects malformed chunk framing before it reaches httpd.\n* Restrict access to the server to trusted clients where the deployment allows it."
}
],
"value": "* Set minimum_bytes_per_second in the httpd configuration, for example {minimum_bytes_per_second, 200}. This arms a periodic byte-rate check that terminates a connection which has stopped delivering data, reclaiming the parked worker within a few seconds. The check is disabled by default, and any positive value suffices because an affected connection delivers no further data at all.\n* Place a reverse proxy in front of httpd that validates chunked transfer encoding and rejects malformed chunk framing before it reaches httpd.\n* Restrict access to the server to trusted clients where the deployment allows it."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-69664",
"datePublished": "2026-09-01T14:59:03.512Z",
"dateReserved": "2026-08-17T10:45:02.808Z",
"dateUpdated": "2026-09-22T09:10:07.550Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-66835 (GCVE-0-2026-66835)
Vulnerability from nvd – Published: 2026-09-01 14:49 – Updated: 2026-09-08 01:08
VLAI
EPSS
VEX
Title
httpd mod_auth directory protection bypassed by a doubled slash in the request path
Summary
Path Equivalence vulnerability in Erlang/OTP inets httpd allows a remote unauthenticated attacker to read files inside a mod_auth protected directory by prefixing the request path with an extra slash.
httpd_request:validate_uri/1 normalises the request URI with uri_string:normalize/1, which performs RFC 3986 dot-segment removal but does not collapse empty path segments, so a doubled slash survives. mod_alias:real_name/3 concatenates the document root with that URI, and mod_auth:secret_path/3 then decides whether the result lies inside a protected directory block by running the configured directory path as an unanchored regular expression against it. The doubled slash breaks the contiguous substring the regex needs, so the request is treated as unprotected and no authentication challenge is issued, while mod_get opens the same path and the operating system collapses the doubled slash and returns the protected file. The same path mismatch also evades the per-path accounting in mod_security.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP 17.0, corresponding to inets before 5.10, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 17:57 UTC
CWE
- CWE-50 - Path Equivalence: '//multiple/leading/slash'
Assigner
References
7 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-66835.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-66835 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/bac19eb3dbd9… | patch |
| https://github.com/erlang/otp/commit/d8878dec0ece… | patch |
| https://github.com/erlang/otp/commit/9641944a2efb… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 5.10
(otp)
Affected: 5.10 , < 9.3.2.7 (otp) Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-66835",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T17:57:48.578657Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T17:58:31.739Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"mod_auth",
"mod_alias",
"httpd_request"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_server/mod_auth.erl",
"lib/inets/src/http_server/mod_alias.erl",
"lib/inets/src/http_server/httpd_request.erl"
],
"programRoutines": [
{
"name": "mod_auth:secret_path/3"
},
{
"name": "mod_alias:real_name/3"
},
{
"name": "httpd_request:validate_uri/1"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"mod_auth",
"mod_alias",
"httpd_request"
],
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"programFiles": [
"src/http_server/mod_auth.erl",
"src/http_server/mod_alias.erl",
"src/http_server/httpd_request.erl"
],
"programRoutines": [
{
"name": "mod_auth:secret_path/3"
},
{
"name": "mod_alias:real_name/3"
},
{
"name": "httpd_request:validate_uri/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "5.10",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "5.10",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"mod_auth",
"mod_alias",
"httpd_request"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/inets/src/http_server/mod_auth.erl",
"lib/inets/src/http_server/mod_alias.erl",
"lib/inets/src/http_server/httpd_request.erl"
],
"programRoutines": [
{
"name": "mod_auth:secret_path/3"
},
{
"name": "mod_alias:real_name/3"
},
{
"name": "httpd_request:validate_uri/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "bac19eb3dbd96cc49b6d8cabc1c04248bf8c79f6",
"status": "unaffected"
},
{
"at": "d8878dec0ececc2eab18e47bb18b472f224ca633",
"status": "unaffected"
},
{
"at": "9641944a2efbf55bea760f8ff7ba777fe3a0961c",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eOnly servers that protect a directory with \u003ccode\u003emod_auth\u003c/code\u003e, by configuring a \u003ccode\u003edirectory\u003c/code\u003e block with authentication requirements, are affected. A server that serves no authenticated directory has no protection for this issue to bypass.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Only servers that protect a directory with `mod_auth`, by configuring a `directory` block with authentication requirements, are affected. A server that serves no authenticated directory has no protection for this issue to bypass."
}
],
"value": "Only servers that protect a directory with mod_auth, by configuring a directory block with authentication requirements, are affected. A server that serves no authenticated directory has no protection for this issue to bypass."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "reporter",
"value": "Arthur Chan / Ada Logics"
},
{
"lang": "en",
"type": "reporter",
"value": "David Korczynski / Ada Logics"
},
{
"lang": "en",
"type": "reporter",
"value": "Adam Korczynski / Ada Logics"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003ePath Equivalence vulnerability in Erlang/OTP inets httpd allows a remote unauthenticated attacker to read files inside a \u003ccode\u003emod_auth\u003c/code\u003e protected directory by prefixing the request path with an extra slash.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ehttpd_request:validate_uri/1\u003c/code\u003e normalises the request URI with \u003ccode\u003euri_string:normalize/1\u003c/code\u003e, which performs RFC 3986 dot-segment removal but does not collapse empty path segments, so a doubled slash survives. \u003ccode\u003emod_alias:real_name/3\u003c/code\u003e concatenates the document root with that URI, and \u003ccode\u003emod_auth:secret_path/3\u003c/code\u003e then decides whether the result lies inside a protected \u003ccode\u003edirectory\u003c/code\u003e block by running the configured directory path as an unanchored regular expression against it. The doubled slash breaks the contiguous substring the regex needs, so the request is treated as unprotected and no authentication challenge is issued, while \u003ccode\u003emod_get\u003c/code\u003e opens the same path and the operating system collapses the doubled slash and returns the protected file. The same path mismatch also evades the per-path accounting in \u003ccode\u003emod_security\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u0026nbsp;17.0, corresponding to inets before 5.10, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Path Equivalence vulnerability in Erlang/OTP inets httpd allows a remote unauthenticated attacker to read files inside a `mod_auth` protected directory by prefixing the request path with an extra slash.\n\n`httpd_request:validate_uri/1` normalises the request URI with `uri_string:normalize/1`, which performs RFC 3986 dot-segment removal but does not collapse empty path segments, so a doubled slash survives. `mod_alias:real_name/3` concatenates the document root with that URI, and `mod_auth:secret_path/3` then decides whether the result lies inside a protected `directory` block by running the configured directory path as an unanchored regular expression against it. The doubled slash breaks the contiguous substring the regex needs, so the request is treated as unprotected and no authentication challenge is issued, while `mod_get` opens the same path and the operating system collapses the doubled slash and returns the protected file. The same path mismatch also evades the per-path accounting in `mod_security`.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"value": "Path Equivalence vulnerability in Erlang/OTP inets httpd allows a remote unauthenticated attacker to read files inside a mod_auth protected directory by prefixing the request path with an extra slash.\n\nhttpd_request:validate_uri/1 normalises the request URI with uri_string:normalize/1, which performs RFC 3986 dot-segment removal but does not collapse empty path segments, so a doubled slash survives. mod_alias:real_name/3 concatenates the document root with that URI, and mod_auth:secret_path/3 then decides whether the result lies inside a protected directory block by running the configured directory path as an unanchored regular expression against it. The doubled slash breaks the contiguous substring the regex needs, so the request is treated as unprotected and no authentication challenge is issued, while mod_get opens the same path and the operating system collapses the doubled slash and returns the protected file. The same path mismatch also evades the per-path accounting in mod_security.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-126",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-126 Path Traversal"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.2,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-50",
"description": "CWE-50 Path Equivalence: \u0027//multiple/leading/slash\u0027",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:08:16.964Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-r4vv-vc2c-2fw6"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-66835.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-66835"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/bac19eb3dbd96cc49b6d8cabc1c04248bf8c79f6"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/d8878dec0ececc2eab18e47bb18b472f224ca633"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/9641944a2efbf55bea760f8ff7ba777fe3a0961c"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "httpd mod_auth directory protection bypassed by a doubled slash in the request path"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-66835",
"datePublished": "2026-09-01T14:49:47.805Z",
"dateReserved": "2026-08-17T12:00:02.063Z",
"dateUpdated": "2026-09-08T01:08:16.964Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-66357 (GCVE-0-2026-66357)
Vulnerability from nvd – Published: 2026-09-01 14:40 – Updated: 2026-09-08 01:08
VLAI
EPSS
VEX
Title
inets,httpd:HTTP Request Smuggling via obs-fold Header Continuation
Summary
httpd has never implemented obs-fold (RFC 2616 §2.2 / RFC 7230 §3.2.4 header continuation lines). Every CRLF followed by a non-CRLF octet unconditionally starts a new header. This missing feature became a security concern as the understanding of HTTP request smuggling attacks evolved.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP 17.0, corresponding to inets before 5.10, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:56 UTC
CWE
- CWE-444 - Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling')
Assigner
References
6 references
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 5.10
(otp)
Affected: 5.10 , < 9.3.2.7 (otp) Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-66357",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:56:00.806246Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:56:07.942Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "5.10",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "5.10",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "220d618d2479a7180b4a06d0c5aacfaa4af4a85b",
"status": "unaffected"
},
{
"at": "273d8958de38ff2a7fe0c5dcc5b6bfe6f65717f3",
"status": "unaffected"
},
{
"at": "e640d599287d2eba919e6f13b91f042d7dbe6ff4",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Lukas Backstr\u00f6m / Erlang Solutions"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003ehttpd has never implemented obs-fold (RFC 2616 \u00a72.2 / RFC 7230 \u00a73.2.4 header continuation lines). Every CRLF followed by a non-CRLF octet unconditionally starts a new header. This missing feature became a security concern as the understanding of HTTP request smuggling attacks evolved.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u0026nbsp;17.0, corresponding to inets before 5.10, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "httpd has never implemented obs-fold (RFC 2616 \u00a72.2 / RFC 7230 \u00a73.2.4 header continuation lines). Every CRLF followed by a non-CRLF octet unconditionally starts a new header. This missing feature became a security concern as the understanding of HTTP request smuggling attacks evolved.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"value": "httpd has never implemented obs-fold (RFC 2616 \u00a72.2 / RFC 7230 \u00a73.2.4 header continuation lines). Every CRLF followed by a non-CRLF octet unconditionally starts a new header. This missing feature became a security concern as the understanding of HTTP request smuggling attacks evolved.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-33",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-33 HTTP Request Smuggling"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.3,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "LOW",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:H/VA:N/SC:N/SI:L/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "LOW",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-444",
"description": "CWE-444 Inconsistent Interpretation of HTTP Requests (\u0027HTTP Request/Response Smuggling\u0027)",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:08:00.943Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-qh2f-33hj-37qf"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-66357.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-66357"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/220d618d2479a7180b4a06d0c5aacfaa4af4a85b"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/273d8958de38ff2a7fe0c5dcc5b6bfe6f65717f3"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/e640d599287d2eba919e6f13b91f042d7dbe6ff4"
}
],
"source": {
"discovery": "UNKNOWN"
},
"title": "inets,httpd:HTTP Request Smuggling via obs-fold Header Continuation"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-66357",
"datePublished": "2026-09-01T14:40:50.526Z",
"dateReserved": "2026-08-17T20:00:02.207Z",
"dateUpdated": "2026-09-08T01:08:00.943Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-59696 (GCVE-0-2026-59696)
Vulnerability from nvd – Published: 2026-09-01 14:37 – Updated: 2026-09-08 01:07
VLAI
EPSS
VEX
Title
uri_string does not bound the port component of a URI before integer conversion
Summary
Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP stdlib allows a remote attacker to degrade availability by supplying a URI whose port component is a very long run of digits.
uri_string:get_port/1 passes the port substring to binary_to_integer/1 with no length bound, catching only error:badarg, so a syntactically valid port of up to roughly 1.26 million digits converts successfully and costs the calling process hundreds of milliseconds of arbitrary-precision arithmetic. The conversion is reached from every authority-parsing path in uri_string:parse/1, including the host, registered-name, and IPv4 and IPv6 forms. parse/1 is the documented interface for parsing URIs, so any application that parses an attacker-supplied URI is exposed without further configuration. The conversion function is documented to accept integers of any size, so bounding the input is the caller's responsibility.
This issue affects OTP from OTP 21.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to stdlib from 3.5 before 6.2.2.5, from 7.0 before 7.3.0.2, and from 8.0 before 8.0.4.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:54 UTC
CWE
- CWE-1284 - Improper Validation of Specified Quantity in Input
Assigner
References
6 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisory |
| https://cna.erlef.org/cves/CVE-2026-59696.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-59696 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/aba0fe8c2d70… | patch |
| https://github.com/erlang/otp/commit/e3be1cfe9f6c… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Affected:
21.0 , < 27.3.4.17
(otp)
Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
3.5 , < 6.2.2.5
(otp)
Affected: 7.0 , < 7.3.0.2 (otp) Affected: 8.0 , < 8.0.4 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
29a9dd0e17a97a3e6e46f0d08c6ba8f31db33f5e , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-59696",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:54:42.891377Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:54:49.733Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"uri_string"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/stdlib/src/uri_string.erl"
],
"programRoutines": [
{
"name": "uri_string:get_port/1"
},
{
"name": "uri_string:parse/1"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "21.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"uri_string"
],
"packageName": "stdlib",
"packageURL": "pkg:otp/stdlib",
"product": "OTP",
"programFiles": [
"src/uri_string.erl"
],
"programRoutines": [
{
"name": "uri_string:get_port/1"
},
{
"name": "uri_string:parse/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "6.2.2.5",
"status": "affected",
"version": "3.5",
"versionType": "otp"
},
{
"lessThan": "7.3.0.2",
"status": "affected",
"version": "7.0",
"versionType": "otp"
},
{
"lessThan": "8.0.4",
"status": "affected",
"version": "8.0",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"uri_string"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/stdlib/src/uri_string.erl"
],
"programRoutines": [
{
"name": "uri_string:get_port/1"
},
{
"name": "uri_string:parse/1"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d",
"status": "unaffected"
},
{
"at": "e3be1cfe9f6cedd0cd20d9905e05601dfb31c8aa",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "29a9dd0e17a97a3e6e46f0d08c6ba8f31db33f5e",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"versionStartIncluding": "21.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Eric Meadows-J\u00f6nsson"
},
{
"lang": "en",
"type": "finder",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "finder",
"value": "Peter Ullrich"
},
{
"lang": "en",
"type": "finder",
"value": "Jos\u00e9 Valim"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
},
{
"lang": "en",
"type": "analyst",
"value": "Ingela Anderton Andin"
},
{
"lang": "en",
"type": "analyst",
"value": "Dan Gudmundsson"
},
{
"lang": "en",
"type": "analyst",
"value": "John H\u00f6gberg"
},
{
"lang": "en",
"type": "analyst",
"value": "Rickard Green"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eImproper Validation of Specified Quantity in Input vulnerability in Erlang/OTP stdlib allows a remote attacker to degrade availability by supplying a URI whose port component is a very long run of digits.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003euri_string:get_port/1\u003c/code\u003e passes the port substring to \u003ccode\u003ebinary_to_integer/1\u003c/code\u003e with no length bound, catching only \u003ccode\u003eerror:badarg\u003c/code\u003e, so a syntactically valid port of up to roughly 1.26 million digits converts successfully and costs the calling process hundreds of milliseconds of arbitrary-precision arithmetic. The conversion is reached from every authority-parsing path in \u003ccode\u003euri_string:parse/1\u003c/code\u003e, including the host, registered-name, and IPv4 and IPv6 forms. \u003ccode\u003eparse/1\u003c/code\u003e is the documented interface for parsing URIs, so any application that parses an attacker-supplied URI is exposed without further configuration. The conversion function is documented to accept integers of any size, so bounding the input is the caller\u0027s responsibility.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;21.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to stdlib from 3.5 before 6.2.2.5, from 7.0 before 7.3.0.2, and from 8.0 before 8.0.4.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP stdlib allows a remote attacker to degrade availability by supplying a URI whose port component is a very long run of digits.\n\n`uri_string:get_port/1` passes the port substring to `binary_to_integer/1` with no length bound, catching only `error:badarg`, so a syntactically valid port of up to roughly 1.26 million digits converts successfully and costs the calling process hundreds of milliseconds of arbitrary-precision arithmetic. The conversion is reached from every authority-parsing path in `uri_string:parse/1`, including the host, registered-name, and IPv4 and IPv6 forms. `parse/1` is the documented interface for parsing URIs, so any application that parses an attacker-supplied URI is exposed without further configuration. The conversion function is documented to accept integers of any size, so bounding the input is the caller\u0027s responsibility.\n\nThis issue affects OTP from OTP\u00a021.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to stdlib from 3.5 before 6.2.2.5, from 7.0 before 7.3.0.2, and from 8.0 before 8.0.4."
}
],
"value": "Improper Validation of Specified Quantity in Input vulnerability in Erlang/OTP stdlib allows a remote attacker to degrade availability by supplying a URI whose port component is a very long run of digits.\n\nuri_string:get_port/1 passes the port substring to binary_to_integer/1 with no length bound, catching only error:badarg, so a syntactically valid port of up to roughly 1.26 million digits converts successfully and costs the calling process hundreds of milliseconds of arbitrary-precision arithmetic. The conversion is reached from every authority-parsing path in uri_string:parse/1, including the host, registered-name, and IPv4 and IPv6 forms. parse/1 is the documented interface for parsing URIs, so any application that parses an attacker-supplied URI is exposed without further configuration. The conversion function is documented to accept integers of any size, so bounding the input is the caller\u0027s responsibility.\n\nThis issue affects OTP from OTP\u00a021.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to stdlib from 3.5 before 6.2.2.5, from 7.0 before 7.3.0.2, and from 8.0 before 8.0.4."
}
],
"impacts": [
{
"capecId": "CAPEC-231",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-231 Oversized Serialized Data Payloads"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 6.9,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "LOW",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-1284",
"description": "CWE-1284 Improper Validation of Specified Quantity in Input",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:07:47.936Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-8qw4-2chm-mvj2"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-59696.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-59696"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/e3be1cfe9f6cedd0cd20d9905e05601dfb31c8aa"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "uri_string does not bound the port component of a URI before integer conversion"
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-59696",
"datePublished": "2026-09-01T14:37:33.697Z",
"dateReserved": "2026-07-06T14:05:47.003Z",
"dateUpdated": "2026-09-08T01:07:47.936Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-55951 (GCVE-0-2026-55951)
Vulnerability from nvd – Published: 2026-09-01 14:37 – Updated: 2026-09-08 01:06
VLAI
EPSS
VEX
Title
httpc memory exhaustion via unbounded response header accumulation
Summary
The Erlang/OTP httpc HTTP client does not enforce a limit on the total size of response headers received from a server. The max_header_size option defaults to nolimit, and httpc_response:parse_headers/6 accumulates every header into a list before the length check runs (which only fires after the terminating CRLF CRLF is received).
A malicious or compromised HTTP server can send an arbitrarily large number of headers, or headers with very large values, causing the client process to allocate unbounded memory until the system runs out of memory or the BEAM VM crashes. A proof-of-concept server sending 100,000 headers of roughly 4000 bytes each caused the client VM to allocate over 13 GB of memory in under 30 seconds.
Any application using httpc:request/4,5 to connect to untrusted servers is affected. No authentication is required: any server the client connects to (including via a redirect or man-in-the-middle) can trigger the exhaustion.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.17, from OTP 28.0 before OTP 28.5.0.6, and from OTP 29.0 before OTP 29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP 17.0, corresponding to inets before 5.10, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-09-01 15:53 UTC
CWE
- CWE-770 - Allocation of Resources Without Limits or Throttling
Assigner
References
6 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisory |
| https://cna.erlef.org/cves/CVE-2026-55951.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-55951 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/aba0fe8c2d70… | patch |
| https://github.com/erlang/otp/commit/e3be1cfe9f6c… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.17 (otp) Affected: 28.0 , < 28.5.0.6 (otp) Affected: 29.0 , < 29.0.6 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 5.10
(otp)
Affected: 5.10 , < 9.3.2.7 (otp) Affected: 9.4 , < 9.6.2.3 (otp) Affected: 9.7 , < 9.7.2 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-55951",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-09-01T15:53:49.437447Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-09-01T15:54:18.435Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpc_response",
"httpc_handler",
"httpc"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"src/http_client/httpc_response.erl",
"src/http_client/httpc_handler.erl",
"src/http_client/httpc.erl"
],
"programRoutines": [
{
"name": "httpc_response:parse_headers/6"
},
{
"name": "httpc:request/4"
},
{
"name": "httpc:request/5"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.17",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.6",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.6",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"packageName": "inets",
"packageURL": "pkg:otp/inets",
"product": "OTP",
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "5.10",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "9.3.2.7",
"status": "affected",
"version": "5.10",
"versionType": "otp"
},
{
"lessThan": "9.6.2.3",
"status": "affected",
"version": "9.4",
"versionType": "otp"
},
{
"lessThan": "9.7.2",
"status": "affected",
"version": "9.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"httpc_response",
"httpc_handler",
"httpc"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"src/http_client/httpc_response.erl",
"src/http_client/httpc_handler.erl",
"src/http_client/httpc.erl"
],
"programRoutines": [
{
"name": "httpc_response:parse_headers/6"
},
{
"name": "httpc:request/4"
},
{
"name": "httpc:request/5"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d",
"status": "unaffected"
},
{
"at": "e3be1cfe9f6cedd0cd20d9905e05601dfb31c8aa",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.17",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.6",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.6",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "remediation developer",
"value": "Konrad Pietrzak / Ericsson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eThe Erlang/OTP \u003ccode\u003ehttpc\u003c/code\u003e HTTP client does not enforce a limit on the total size of response headers received from a server. The \u003ccode\u003emax_header_size\u003c/code\u003e option defaults to \u003ccode\u003enolimit\u003c/code\u003e, and \u003ccode\u003ehttpc_response:parse_headers/6\u003c/code\u003e accumulates every header into a list before the length check runs (which only fires after the terminating CRLF CRLF is received).\u003c/p\u003e\n\u003cp\u003eA malicious or compromised HTTP server can send an arbitrarily large number of headers, or headers with very large values, causing the client process to allocate unbounded memory until the system runs out of memory or the BEAM VM crashes. A proof-of-concept server sending 100,000 headers of roughly 4000 bytes each caused the client VM to allocate over 13 GB of memory in under 30 seconds.\u003c/p\u003e\n\u003cp\u003eAny application using \u003ccode\u003ehttpc:request/4,5\u003c/code\u003e to connect to untrusted servers is affected. No authentication is required: any server the client connects to (including via a redirect or man-in-the-middle) can trigger the exhaustion.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.17, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.6, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u0026nbsp;17.0, corresponding to inets before 5.10, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "The Erlang/OTP `httpc` HTTP client does not enforce a limit on the total size of response headers received from a server. The `max_header_size` option defaults to `nolimit`, and `httpc_response:parse_headers/6` accumulates every header into a list before the length check runs (which only fires after the terminating CRLF CRLF is received).\n\nA malicious or compromised HTTP server can send an arbitrarily large number of headers, or headers with very large values, causing the client process to allocate unbounded memory until the system runs out of memory or the BEAM VM crashes. A proof-of-concept server sending 100,000 headers of roughly 4000 bytes each caused the client VM to allocate over 13 GB of memory in under 30 seconds.\n\nAny application using `httpc:request/4,5` to connect to untrusted servers is affected. No authentication is required: any server the client connects to (including via a redirect or man-in-the-middle) can trigger the exhaustion.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"value": "The Erlang/OTP httpc HTTP client does not enforce a limit on the total size of response headers received from a server. The max_header_size option defaults to nolimit, and httpc_response:parse_headers/6 accumulates every header into a list before the length check runs (which only fires after the terminating CRLF CRLF is received).\n\nA malicious or compromised HTTP server can send an arbitrarily large number of headers, or headers with very large values, causing the client process to allocate unbounded memory until the system runs out of memory or the BEAM VM crashes. A proof-of-concept server sending 100,000 headers of roughly 4000 bytes each caused the client VM to allocate over 13 GB of memory in under 30 seconds.\n\nAny application using httpc:request/4,5 to connect to untrusted servers is affected. No authentication is required: any server the client connects to (including via a redirect or man-in-the-middle) can trigger the exhaustion.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.17, from OTP\u00a028.0 before OTP\u00a028.5.0.6, and from OTP\u00a029.0 before OTP\u00a029.0.6, corresponding to inets from 5.10 before 9.3.2.7, from 9.4 before 9.6.2.3, and from 9.7 before 9.7.2. Whether OTP before OTP\u00a017.0, corresponding to inets before 5.10, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-130",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-130 Excessive Allocation"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.2,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-770",
"description": "CWE-770 Allocation of Resources Without Limits or Throttling",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:06:43.872Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-f9fw-mg7q-4g3x"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-55951.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-55951"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/aba0fe8c2d700bf4ac94607cf7f00e53bbe4042d"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/e3be1cfe9f6cedd0cd20d9905e05601dfb31c8aa"
}
],
"source": {
"discovery": "UNKNOWN"
},
"title": "httpc memory exhaustion via unbounded response header accumulation",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cul\u003e\n\u003cli\u003eRestrict \u003ccode\u003ehttpc\u003c/code\u003e to trusted servers only, and avoid using it to fetch resources from arbitrary or user-supplied URLs.\u003c/li\u003e\n\u003cli\u003eApply operating-system memory limits (cgroups,\u003ccode\u003eulimit\u003c/code\u003e) to contain the blast radius of a runaway client process.\u003c/li\u003e\n\u003cli\u003eUse an alternative HTTP client library that enforces a response header size limit.\u003c/li\u003e\n\u003c/ul\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "* Restrict `httpc` to trusted servers only, and avoid using it to fetch resources from arbitrary or user-supplied URLs.\n* Apply operating-system memory limits (cgroups,`ulimit`) to contain the blast radius of a runaway client process.\n* Use an alternative HTTP client library that enforces a response header size limit."
}
],
"value": "* Restrict httpc to trusted servers only, and avoid using it to fetch resources from arbitrary or user-supplied URLs.\n* Apply operating-system memory limits (cgroups,ulimit) to contain the blast radius of a runaway client process.\n* Use an alternative HTTP client library that enforces a response header size limit."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-55951",
"datePublished": "2026-09-01T14:37:02.650Z",
"dateReserved": "2026-06-17T17:55:15.685Z",
"dateUpdated": "2026-09-08T01:06:43.872Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-59251 (GCVE-0-2026-59251)
Vulnerability from nvd – Published: 2026-07-27 15:30 – Updated: 2026-07-28 09:54
VLAI
EPSS
VEX
Title
Denial of service via exponential certificate policy tree growth in path validation
Summary
Allocation of resources without limits in Erlang/OTP public_key certificate path validation allows a remote unauthenticated attacker to cause denial of service by sending a crafted X.509 certificate chain during the TLS handshake.
During RFC 5280 policy processing in public_key:pkix_path_validation/3, the certificate policy tree maintained by pubkey_policy_tree grows without an upper bound. When a certificate chain contains M policies per certificate and K certificates, the tree grows on the order of M^K nodes because pubkey_policy_tree:add_leaves/2 and pubkey_policy_tree:add_leaf_siblings/2 extend the tree per policy per certificate. A modest chain with many policies per certificate is enough to pin BEAM schedulers and exhaust the node's memory, taking down the entire VM. The attacker only needs to be able to present a certificate chain to the victim, which is the normal precondition for a TLS handshake, so exploitation succeeds against any incoming or outgoing TLS connection that validates the peer's chain (the default for SSL/TLS clients and mutual-TLS servers).
This is the same vulnerability class as OpenSSL's X509_verify_cert policy tree DoS.
This vulnerability is associated with program files lib/public_key/src/pubkey_policy_tree.erl and program routines pubkey_policy_tree:add_leaves/2 and pubkey_policy_tree:add_leaf_siblings/2.
This issue affects OTP from OTP 26.2 before OTP 29.0.4, OTP 28.5.0.4 and OTP 27.3.4.15, corresponding to public_key from 1.15 before 1.21.4, 1.20.3.4 and 1.17.1.5.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-07-27 18:31 UTC
CWE
- CWE-770 - Allocation of Resources Without Limits or Throttling
Assigner
References
6 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-59251.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-59251 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/f8580fc11709… | patch |
| https://github.com/erlang/otp/commit/f04c6bba38de… | patch |
Impacted products
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-59251",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-27T18:31:50.981990Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-07-27T18:32:09.923Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"pubkey_policy_tree"
],
"packageName": "public_key",
"packageURL": "pkg:otp/public_key?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Fotp\u0026vcs_url=git%20https:%2F%2Fgithub.com%2Ferlang%2Fotp.git",
"product": "OTP",
"programFiles": [
"src/pubkey_policy_tree.erl"
],
"programRoutines": [
{
"name": "pubkey_policy_tree:add_leaves/2"
},
{
"name": "pubkey_policy_tree:add_leaf_siblings/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "1.21.4",
"status": "unaffected"
},
{
"at": "1.20.3.4",
"status": "unaffected"
},
{
"at": "1.17.1.5",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "1.15",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"pubkey_policy_tree"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/public_key/src/pubkey_policy_tree.erl"
],
"programRoutines": [
{
"name": "pubkey_policy_tree:add_leaves/2"
},
{
"name": "pubkey_policy_tree:add_leaf_siblings/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "29.0.4",
"status": "unaffected"
},
{
"at": "28.5.0.4",
"status": "unaffected"
},
{
"at": "27.3.4.15",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "26.2",
"versionType": "otp"
},
{
"changes": [
{
"at": "f8580fc117098c08165f46c26fd0750c5cfb2a90",
"status": "unaffected"
},
{
"at": "f04c6bba38de1cf1b1836a7d9a9fbe239bd939e8",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "9d1dda7bad5a64b58c10a1554751689e94131a73",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.15",
"versionStartIncluding": "26.2",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.4",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.4",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Lukas Backstr\u00f6m"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Jakub Witczak"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Micha\u0142 W\u0105sowski"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eAllocation of resources without limits in Erlang/OTP public_key certificate path validation allows a remote unauthenticated attacker to cause denial of service by sending a crafted X.509 certificate chain during the TLS handshake.\u003c/p\u003e\u003cp\u003eDuring RFC 5280 policy processing in \u003ctt\u003epublic_key:pkix_path_validation/3\u003c/tt\u003e, the certificate policy tree maintained by \u003ctt\u003epubkey_policy_tree\u003c/tt\u003e grows without an upper bound. When a certificate chain contains M policies per certificate and K certificates, the tree grows on the order of M^K nodes because \u003ctt\u003epubkey_policy_tree:add_leaves/2\u003c/tt\u003e and \u003ctt\u003epubkey_policy_tree:add_leaf_siblings/2\u003c/tt\u003e extend the tree per policy per certificate. A modest chain with many policies per certificate is enough to pin BEAM schedulers and exhaust the node\u0027s memory, taking down the entire VM. The attacker only needs to be able to present a certificate chain to the victim, which is the normal precondition for a TLS handshake, so exploitation succeeds against any incoming or outgoing TLS connection that validates the peer\u0027s chain (the default for SSL/TLS clients and mutual-TLS servers).\u003c/p\u003e\u003cp\u003eThis is the same vulnerability class as OpenSSL\u0027s \u003ctt\u003eX509_verify_cert\u003c/tt\u003e policy tree DoS.\u003c/p\u003e\u003cp\u003eThis vulnerability is associated with program files \u003ctt\u003elib/public_key/src/pubkey_policy_tree.erl\u003c/tt\u003e and program routines \u003ctt\u003epubkey_policy_tree:add_leaves/2\u003c/tt\u003e and \u003ctt\u003epubkey_policy_tree:add_leaf_siblings/2\u003c/tt\u003e.\u003c/p\u003e\u003cp\u003eThis issue affects OTP from OTP 26.2 before OTP\u0026nbsp;29.0.4, OTP\u0026nbsp;28.5.0.4 and OTP\u0026nbsp;27.3.4.15, corresponding to public_key from 1.15 before 1.21.4, 1.20.3.4 and 1.17.1.5.\u003c/p\u003e"
}
],
"value": "Allocation of resources without limits in Erlang/OTP public_key certificate path validation allows a remote unauthenticated attacker to cause denial of service by sending a crafted X.509 certificate chain during the TLS handshake.\n\nDuring RFC 5280 policy processing in public_key:pkix_path_validation/3, the certificate policy tree maintained by pubkey_policy_tree grows without an upper bound. When a certificate chain contains M policies per certificate and K certificates, the tree grows on the order of M^K nodes because pubkey_policy_tree:add_leaves/2 and pubkey_policy_tree:add_leaf_siblings/2 extend the tree per policy per certificate. A modest chain with many policies per certificate is enough to pin BEAM schedulers and exhaust the node\u0027s memory, taking down the entire VM. The attacker only needs to be able to present a certificate chain to the victim, which is the normal precondition for a TLS handshake, so exploitation succeeds against any incoming or outgoing TLS connection that validates the peer\u0027s chain (the default for SSL/TLS clients and mutual-TLS servers).\n\nThis is the same vulnerability class as OpenSSL\u0027s X509_verify_cert policy tree DoS.\n\nThis vulnerability is associated with program files lib/public_key/src/pubkey_policy_tree.erl and program routines pubkey_policy_tree:add_leaves/2 and pubkey_policy_tree:add_leaf_siblings/2.\n\nThis issue affects OTP from OTP 26.2 before OTP\u00a029.0.4, OTP\u00a028.5.0.4 and OTP\u00a027.3.4.15, corresponding to public_key from 1.15 before 1.21.4, 1.20.3.4 and 1.17.1.5."
}
],
"impacts": [
{
"capecId": "CAPEC-130",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-130 Excessive Allocation"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 8.7,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"subAvailabilityImpact": "LOW",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:L",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-770",
"description": "CWE-770 Allocation of Resources Without Limits or Throttling",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-07-28T09:54:59.169Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-622p-qfh6-c352"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-59251.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-59251"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/f8580fc117098c08165f46c26fd0750c5cfb2a90"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/f04c6bba38de1cf1b1836a7d9a9fbe239bd939e8"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Denial of service via exponential certificate policy tree growth in path validation",
"x_generator": {
"engine": "cvelib 1.8.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-59251",
"datePublished": "2026-07-27T15:30:47.097Z",
"dateReserved": "2026-07-04T04:24:03.653Z",
"dateUpdated": "2026-07-28T09:54:59.169Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-59250 (GCVE-0-2026-59250)
Vulnerability from nvd – Published: 2026-07-27 15:25 – Updated: 2026-09-08 01:07
VLAI
EPSS
VEX
Title
Megaco flex scanner buffer overflow via oversized property parm name
Summary
Classic buffer overflow in the Erlang/OTP megaco flex scanner C driver allows a remote unauthenticated attacker to corrupt the driver's memory (and potentially achieve remote code execution or a denial-of-service crash) by sending a single text-encoded H.248/Megaco message containing an oversized property parm name.
When tokenizing a Local/Remote descriptor, mfs_load_property_groups extracts the attacker-controlled property name (bounded only by the message length) and, when no value follows, formats it into a fixed 512-byte error_msg field of the MfsErlDrvData struct using an unchecked sprintf call. Names longer than roughly 452 bytes overflow into the immediately following struct fields (text_buf, text_ptr, term_spec, term_spec_size, term_spec_index), overwriting live pointers and counters with attacker-chosen bytes. Subsequent scanner code writes and frees through the corrupted pointers, producing arbitrary write and arbitrary free primitives inside the BEAM VM process, which can be leveraged for remote code execution. On builds compiled with _FORTIFY_SOURCE the overflow is detected at runtime and terminates the process with SIGABRT, resulting in denial of service.
The overflow occurs in the flex scanner before any grammar or Megaco-level authentication processing, so exploitation requires only network reachability to the megaco transport port on a node configured with {scanner, flex}.
This vulnerability is associated with program files lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src and program routines mfs_load_property_groups.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.15, from OTP 28.0 before OTP 28.5.0.4, and from OTP 29.0 before OTP 29.0.4, corresponding to megaco from 3.17.1 before 4.7.2.2, from 4.8 before 4.8.3.1, and from 4.9 before 4.9.1. Whether OTP before OTP 17.0, corresponding to megaco before 3.17.1, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-07-27 18:33 UTC
CWE
Assigner
References
5 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-59250.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-59250 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/8704c8f550a1… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.15 (otp) Affected: 28.0 , < 28.5.0.4 (otp) Affected: 29.0 , < 29.0.4 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 3.17.1
(otp)
Affected: 3.17.1 , < 4.7.2.2 (otp) Affected: 4.8 , < 4.8.3.1 (otp) Affected: 4.9 , < 4.9.1 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < 8704c8f550a11ed5f825e3c011ecb03565b79c4f
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-59250",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-27T18:33:04.735708Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-07-27T18:33:14.927Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"megaco_flex_scanner",
"megaco_flex_scanner_drv"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src"
],
"programRoutines": [
{
"name": "mfs_load_property_groups"
},
{
"name": "megaco_flex_scanner:scan/2"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.15",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.4",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.4",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"megaco_flex_scanner",
"megaco_flex_scanner_drv"
],
"packageName": "megaco",
"packageURL": "pkg:otp/megaco?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Fotp\u0026vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Ferlang%2Fotp.git",
"product": "OTP",
"programFiles": [
"src/flex/megaco_flex_scanner_drv.flex.src"
],
"programRoutines": [
{
"name": "mfs_load_property_groups"
},
{
"name": "megaco_flex_scanner:scan/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "3.17.1",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "4.7.2.2",
"status": "affected",
"version": "3.17.1",
"versionType": "otp"
},
{
"lessThan": "4.8.3.1",
"status": "affected",
"version": "4.8",
"versionType": "otp"
},
{
"lessThan": "4.9.1",
"status": "affected",
"version": "4.9",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"megaco_flex_scanner",
"megaco_flex_scanner_drv"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src"
],
"programRoutines": [
{
"name": "mfs_load_property_groups"
},
{
"name": "megaco_flex_scanner:scan/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "8704c8f550a11ed5f825e3c011ecb03565b79c4f",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eThe megaco text codec must be configured to use the flex scanner via the encoder option \u003ccode\u003e{scanner, flex}\u003c/code\u003e (the documented high-performance configuration). Deployments using the default Erlang-based scanner are not affected.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "The megaco text codec must be configured to use the flex scanner via the encoder option `{scanner, flex}` (the documented high-performance configuration). Deployments using the default Erlang-based scanner are not affected."
}
],
"value": "The megaco text codec must be configured to use the flex scanner via the encoder option {scanner, flex} (the documented high-performance configuration). Deployments using the default Erlang-based scanner are not affected."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.15",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.4",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.4",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Jakub Witczak"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Micael Karlberg"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eClassic buffer overflow in the Erlang/OTP megaco flex scanner C driver allows a remote unauthenticated attacker to corrupt the driver\u0027s memory (and potentially achieve remote code execution or a denial-of-service crash) by sending a single text-encoded H.248/Megaco message containing an oversized property parm name.\u003c/p\u003e\n\u003cp\u003eWhen tokenizing a Local/Remote descriptor, \u003ccode\u003emfs_load_property_groups\u003c/code\u003e extracts the attacker-controlled property name (bounded only by the message length) and, when no value follows, formats it into a fixed 512-byte \u003ccode\u003eerror_msg\u003c/code\u003e field of the \u003ccode\u003eMfsErlDrvData\u003c/code\u003e struct using an unchecked \u003ccode\u003esprintf\u003c/code\u003e call. Names longer than roughly 452 bytes overflow into the immediately following struct fields (\u003ccode\u003etext_buf\u003c/code\u003e, \u003ccode\u003etext_ptr\u003c/code\u003e, \u003ccode\u003eterm_spec\u003c/code\u003e, \u003ccode\u003eterm_spec_size\u003c/code\u003e, \u003ccode\u003eterm_spec_index\u003c/code\u003e), overwriting live pointers and counters with attacker-chosen bytes. Subsequent scanner code writes and frees through the corrupted pointers, producing arbitrary write and arbitrary free primitives inside the BEAM VM process, which can be leveraged for remote code execution. On builds compiled with \u003ccode\u003e_FORTIFY_SOURCE\u003c/code\u003e the overflow is detected at runtime and terminates the process with \u003ccode\u003eSIGABRT\u003c/code\u003e, resulting in denial of service.\u003c/p\u003e\n\u003cp\u003eThe overflow occurs in the flex scanner before any grammar or Megaco-level authentication processing, so exploitation requires only network reachability to the megaco transport port on a node configured with \u003ccode\u003e{scanner, flex}\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThis vulnerability is associated with program files \u003ccode\u003elib/megaco/src/flex/megaco_flex_scanner_drv.flex.src\u003c/code\u003e and program routines \u003ccode\u003emfs_load_property_groups\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.15, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.4, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.4, corresponding to megaco from 3.17.1 before 4.7.2.2, from 4.8 before 4.8.3.1, and from 4.9 before 4.9.1. Whether OTP before OTP\u0026nbsp;17.0, corresponding to megaco before 3.17.1, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Classic buffer overflow in the Erlang/OTP megaco flex scanner C driver allows a remote unauthenticated attacker to corrupt the driver\u0027s memory (and potentially achieve remote code execution or a denial-of-service crash) by sending a single text-encoded H.248/Megaco message containing an oversized property parm name.\n\nWhen tokenizing a Local/Remote descriptor, `mfs_load_property_groups` extracts the attacker-controlled property name (bounded only by the message length) and, when no value follows, formats it into a fixed 512-byte `error_msg` field of the `MfsErlDrvData` struct using an unchecked `sprintf` call. Names longer than roughly 452 bytes overflow into the immediately following struct fields (`text_buf`, `text_ptr`, `term_spec`, `term_spec_size`, `term_spec_index`), overwriting live pointers and counters with attacker-chosen bytes. Subsequent scanner code writes and frees through the corrupted pointers, producing arbitrary write and arbitrary free primitives inside the BEAM VM process, which can be leveraged for remote code execution. On builds compiled with `_FORTIFY_SOURCE` the overflow is detected at runtime and terminates the process with `SIGABRT`, resulting in denial of service.\n\nThe overflow occurs in the flex scanner before any grammar or Megaco-level authentication processing, so exploitation requires only network reachability to the megaco transport port on a node configured with `{scanner, flex}`.\n\nThis vulnerability is associated with program files `lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src` and program routines `mfs_load_property_groups`.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.15, from OTP\u00a028.0 before OTP\u00a028.5.0.4, and from OTP\u00a029.0 before OTP\u00a029.0.4, corresponding to megaco from 3.17.1 before 4.7.2.2, from 4.8 before 4.8.3.1, and from 4.9 before 4.9.1. Whether OTP before OTP\u00a017.0, corresponding to megaco before 3.17.1, is affected is unknown."
}
],
"value": "Classic buffer overflow in the Erlang/OTP megaco flex scanner C driver allows a remote unauthenticated attacker to corrupt the driver\u0027s memory (and potentially achieve remote code execution or a denial-of-service crash) by sending a single text-encoded H.248/Megaco message containing an oversized property parm name.\n\nWhen tokenizing a Local/Remote descriptor, mfs_load_property_groups extracts the attacker-controlled property name (bounded only by the message length) and, when no value follows, formats it into a fixed 512-byte error_msg field of the MfsErlDrvData struct using an unchecked sprintf call. Names longer than roughly 452 bytes overflow into the immediately following struct fields (text_buf, text_ptr, term_spec, term_spec_size, term_spec_index), overwriting live pointers and counters with attacker-chosen bytes. Subsequent scanner code writes and frees through the corrupted pointers, producing arbitrary write and arbitrary free primitives inside the BEAM VM process, which can be leveraged for remote code execution. On builds compiled with _FORTIFY_SOURCE the overflow is detected at runtime and terminates the process with SIGABRT, resulting in denial of service.\n\nThe overflow occurs in the flex scanner before any grammar or Megaco-level authentication processing, so exploitation requires only network reachability to the megaco transport port on a node configured with {scanner, flex}.\n\nThis vulnerability is associated with program files lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src and program routines mfs_load_property_groups.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.15, from OTP\u00a028.0 before OTP\u00a028.5.0.4, and from OTP\u00a029.0 before OTP\u00a029.0.4, corresponding to megaco from 3.17.1 before 4.7.2.2, from 4.8 before 4.8.3.1, and from 4.9 before 4.9.1. Whether OTP before OTP\u00a017.0, corresponding to megaco before 3.17.1, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-100",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-100 Overflow Buffers"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.3,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "LOW",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-120",
"description": "CWE-120 Buffer Copy without Checking Size of Input (\u0027Classic Buffer Overflow\u0027)",
"lang": "en",
"type": "CWE"
}
]
},
{
"descriptions": [
{
"cweId": "CWE-787",
"description": "CWE-787 Out-of-bounds Write",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:07:34.932Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-7xgh-gmgf-q2g7"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-59250.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-59250"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/8704c8f550a11ed5f825e3c011ecb03565b79c4f"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "Megaco flex scanner buffer overflow via oversized property parm name",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eSwitch the megaco text codec to the default Erlang-based scanner by removing \u003ccode\u003e{scanner, flex}\u003c/code\u003e from the encoder configuration. The Erlang scanner is not affected by this C-level memory corruption, at the cost of reduced parsing throughput.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "Switch the megaco text codec to the default Erlang-based scanner by removing `{scanner, flex}` from the encoder configuration. The Erlang scanner is not affected by this C-level memory corruption, at the cost of reduced parsing throughput."
}
],
"value": "Switch the megaco text codec to the default Erlang-based scanner by removing {scanner, flex} from the encoder configuration. The Erlang scanner is not affected by this C-level memory corruption, at the cost of reduced parsing throughput."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-59250",
"datePublished": "2026-07-27T15:25:03.106Z",
"dateReserved": "2026-07-04T04:24:03.653Z",
"dateUpdated": "2026-09-08T01:07:34.932Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-58227 (GCVE-0-2026-58227)
Vulnerability from nvd – Published: 2026-07-27 14:39 – Updated: 2026-07-28 09:53
VLAI
EPSS
VEX
Title
TLS/DTLS denial of service via unbounded recursion on cross-signed peer certificate chain
Summary
The Erlang/OTP ssl application does not detect cycles when reconstructing an incomplete peer certificate chain during a TLS or DTLS handshake. In ssl_certificate:handle_incomplete_chain/5, the received chain is passed to ssl_certificate:build_certificate_chain/5, which walks issuer relationships via ssl_certificate:do_certificate_chain/7 with no cycle detection and no depth limit. When the peer supplies two mutually cross-signed certificates in unordered form (A issues B, B issues A), the issuer lookup alternates between the two certificates and the pair of functions recurses indefinitely, growing the call stack and chain accumulator without bound.
An unauthenticated remote attacker can send a crafted certificate chain in a TLS or DTLS Certificate handshake message to exhaust available memory and crash the BEAM node. Only a TCP connection and a partial handshake are required; no authentication or completed handshake is needed, and both TLS/DTLS servers and clients are affected when processing peer certificate messages.
This issue affects OTP from OTP 23.2 before OTP 29.0.4, OTP 28.5.0.4 and OTP 27.3.4.15, corresponding to ssl from 10.2 before 11.7.4, 11.6.0.4 and 11.2.12.11.
Severity
SSVC
Exploitation: none
Automatable: yes
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-07-27 17:25 UTC
CWE
- CWE-674 - Uncontrolled Recursion
Assigner
References
7 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-58227.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-58227 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/0307bff2c72b… | patch |
| https://github.com/erlang/otp/commit/241d43703989… | patch |
| https://github.com/erlang/otp/commit/7db647201779… | patch |
Impacted products
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-58227",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "yes"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-27T17:25:16.012380Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-07-27T17:25:26.884Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"ssl_certificate"
],
"packageName": "ssl",
"packageURL": "pkg:otp/ssl?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Fotp\u0026vcs_url=git%20https:%2F%2Fgithub.com%2Ferlang%2Fotp.git",
"product": "OTP",
"programFiles": [
"src/ssl_certificate.erl"
],
"programRoutines": [
{
"name": "ssl_certificate:handle_incomplete_chain/5"
},
{
"name": "ssl_certificate:build_certificate_chain/5"
},
{
"name": "ssl_certificate:do_certificate_chain/7"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "11.7.4",
"status": "unaffected"
},
{
"at": "11.6.0.4",
"status": "unaffected"
},
{
"at": "11.2.12.11",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "10.2",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"ssl_certificate"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/ssl/src/ssl_certificate.erl"
],
"programRoutines": [
{
"name": "ssl_certificate:handle_incomplete_chain/5"
},
{
"name": "ssl_certificate:build_certificate_chain/5"
},
{
"name": "ssl_certificate:do_certificate_chain/7"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "29.0.4",
"status": "unaffected"
},
{
"at": "28.5.0.4",
"status": "unaffected"
},
{
"at": "27.3.4.15",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "23.2",
"versionType": "otp"
},
{
"changes": [
{
"at": "7db64720177961e04545681480d691c4be81c54d",
"status": "unaffected"
},
{
"at": "241d43703989fec4b6bf637beaeb366d92dcc4c2",
"status": "unaffected"
},
{
"at": "0307bff2c72b685c6bd952daaac6bd661c247d62",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "addc42df113f8f15fc20e9dff45490b3ce0d3d6b",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.15",
"versionStartIncluding": "23.2",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.4",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.4",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Lukas Backstr\u00f6m"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Ingela Anderton Andin"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Dan Gudmundsson"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Jakub Witczak"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "John H\u00f6gberg"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eThe Erlang/OTP \u003ctt\u003essl\u003c/tt\u003e application does not detect cycles when reconstructing an incomplete peer certificate chain during a TLS or DTLS handshake. In \u003ctt\u003essl_certificate:handle_incomplete_chain/5\u003c/tt\u003e, the received chain is passed to \u003ctt\u003essl_certificate:build_certificate_chain/5\u003c/tt\u003e, which walks issuer relationships via \u003ctt\u003essl_certificate:do_certificate_chain/7\u003c/tt\u003e with no cycle detection and no depth limit. When the peer supplies two mutually cross-signed certificates in unordered form (A issues B, B issues A), the issuer lookup alternates between the two certificates and the pair of functions recurses indefinitely, growing the call stack and chain accumulator without bound.\u003c/p\u003e\u003cp\u003eAn unauthenticated remote attacker can send a crafted certificate chain in a TLS or DTLS \u003ctt\u003eCertificate\u003c/tt\u003e handshake message to exhaust available memory and crash the BEAM node. Only a TCP connection and a partial handshake are required; no authentication or completed handshake is needed, and both TLS/DTLS servers and clients are affected when processing peer certificate messages.\u003c/p\u003e\u003cp\u003eThis issue affects OTP from OTP 23.2 before OTP\u0026nbsp;29.0.4, OTP\u0026nbsp;28.5.0.4 and OTP\u0026nbsp;27.3.4.15, corresponding to ssl from 10.2 before 11.7.4, 11.6.0.4 and 11.2.12.11.\u003c/p\u003e"
}
],
"value": "The Erlang/OTP ssl application does not detect cycles when reconstructing an incomplete peer certificate chain during a TLS or DTLS handshake. In ssl_certificate:handle_incomplete_chain/5, the received chain is passed to ssl_certificate:build_certificate_chain/5, which walks issuer relationships via ssl_certificate:do_certificate_chain/7 with no cycle detection and no depth limit. When the peer supplies two mutually cross-signed certificates in unordered form (A issues B, B issues A), the issuer lookup alternates between the two certificates and the pair of functions recurses indefinitely, growing the call stack and chain accumulator without bound.\n\nAn unauthenticated remote attacker can send a crafted certificate chain in a TLS or DTLS Certificate handshake message to exhaust available memory and crash the BEAM node. Only a TCP connection and a partial handshake are required; no authentication or completed handshake is needed, and both TLS/DTLS servers and clients are affected when processing peer certificate messages.\n\nThis issue affects OTP from OTP 23.2 before OTP\u00a029.0.4, OTP\u00a028.5.0.4 and OTP\u00a027.3.4.15, corresponding to ssl from 10.2 before 11.7.4, 11.6.0.4 and 11.2.12.11."
}
],
"impacts": [
{
"capecId": "CAPEC-130",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-130 Excessive Allocation"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "NETWORK",
"baseScore": 8.7,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-674",
"description": "CWE-674 Uncontrolled Recursion",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-07-28T09:53:23.614Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-r5jr-mq46-vmhw"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-58227.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-58227"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/0307bff2c72b685c6bd952daaac6bd661c247d62"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/241d43703989fec4b6bf637beaeb366d92dcc4c2"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/7db64720177961e04545681480d691c4be81c54d"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "TLS/DTLS denial of service via unbounded recursion on cross-signed peer certificate chain",
"x_generator": {
"engine": "cvelib 1.8.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-58227",
"datePublished": "2026-07-27T14:39:44.609Z",
"dateReserved": "2026-06-29T18:54:08.633Z",
"dateUpdated": "2026-07-28T09:53:23.614Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-55953 (GCVE-0-2026-55953)
Vulnerability from nvd – Published: 2026-07-27 15:21 – Updated: 2026-09-08 01:06
VLAI
EPSS
VEX
Title
TLS 1.2 and DTLS client accepts unoffered anonymous cipher suite, bypassing server authentication
Summary
The Erlang/OTP ssl TLS 1.2 (and earlier) and DTLS client does not verify that the cipher suite selected by the server in ServerHello was among the suites offered by the client in ClientHello. The client-side tls_handshake:hello/5 handler validates the negotiated protocol version and the downgrade sentinel but hands the server-chosen suite directly to ssl_handshake:handle_server_hello_extensions/9, which installs it without a membership check. The TLS 1.3 client path performs this check (per RFC 8446), so it is not affected.
An on-path attacker between the client and the intended server can respond with a ServerHello selecting an anonymous key exchange suite such as TLS_DH_anon_* or TLS_ECDH_anon_* that the client never offered. Anonymous suites do not require the server to present a certificate, so the entire verify_peer and cacerts configuration is bypassed: the attacker completes the handshake with its own ephemeral parameters, no certificate is validated, no hostname is checked, and ssl:connect returns {ok, Socket}. All subsequent application traffic is readable and modifiable by the attacker.
This issue affects OTP from OTP 17.0 before OTP 27.3.4.15, from OTP 28.0 before OTP 28.5.0.4, and from OTP 29.0 before OTP 29.0.4, corresponding to ssl from 5.3.4 before 11.2.12.11, from 11.3 before 11.6.0.4, and from 11.7 before 11.7.4. Whether OTP before OTP 17.0, corresponding to ssl before 5.3.4, is affected is unknown.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: total
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-07-27 18:33 UTC
CWE
- CWE-757 - Selection of Less-Secure Algorithm During Negotiation ('Algorithm Downgrade')
Assigner
References
7 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-55953.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-55953 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/064e23641461… | patch |
| https://github.com/erlang/otp/commit/0a82596d425a… | patch |
| https://github.com/erlang/otp/commit/e6ff938116b2… | patch |
Impacted products
3 products
| Vendor | Product | Version | |
|---|---|---|---|
| Erlang | OTP |
Unknown:
0 , < 17.0
(otp)
Affected: 17.0 , < 27.3.4.15 (otp) Affected: 28.0 , < 28.5.0.4 (otp) Affected: 29.0 , < 29.0.4 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Unknown:
0 , < 5.3.4
(otp)
Affected: 5.3.4 , < 11.2.12.11 (otp) Affected: 11.3 , < 11.6.0.4 (otp) Affected: 11.7 , < 11.7.4 (otp) cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
|
| Erlang | OTP |
Affected:
84adefa331c4159d432d22840663c38f155cd4c1 , < *
(git)
cpe:2.3:a:erlang:erlang\/otp:*:*:*:*:*:*:*:* |
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-55953",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "total"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-27T18:33:59.966358Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-07-27T18:34:10.360Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"tls_handshake",
"ssl_handshake",
"ssl"
],
"packageName": "otp",
"packageURL": "pkg:software-id/erlang.org/otp",
"product": "OTP",
"programFiles": [
"lib/ssl/src/tls_handshake.erl",
"lib/ssl/src/ssl_handshake.erl",
"lib/ssl/src/ssl.erl"
],
"programRoutines": [
{
"name": "tls_handshake:hello/5"
},
{
"name": "ssl_handshake:handle_server_hello_extensions/9"
},
{
"name": "ssl:connect/2"
},
{
"name": "ssl:connect/3"
},
{
"name": "ssl:connect/4"
}
],
"vendor": "Erlang",
"versions": [
{
"lessThan": "17.0",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "27.3.4.15",
"status": "affected",
"version": "17.0",
"versionType": "otp"
},
{
"lessThan": "28.5.0.4",
"status": "affected",
"version": "28.0",
"versionType": "otp"
},
{
"lessThan": "29.0.4",
"status": "affected",
"version": "29.0",
"versionType": "otp"
}
]
},
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"tls_handshake",
"ssl_handshake",
"ssl"
],
"packageName": "ssl",
"packageURL": "pkg:otp/ssl?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Fotp\u0026vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Ferlang%2Fotp.git",
"product": "OTP",
"programFiles": [
"src/tls_handshake.erl",
"src/ssl_handshake.erl",
"src/ssl.erl"
],
"programRoutines": [
{
"name": "tls_handshake:hello/5"
},
{
"name": "ssl_handshake:handle_server_hello_extensions/9"
},
{
"name": "ssl:connect/2"
},
{
"name": "ssl:connect/3"
},
{
"name": "ssl:connect/4"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"lessThan": "5.3.4",
"status": "unknown",
"version": "0",
"versionType": "otp"
},
{
"lessThan": "11.2.12.11",
"status": "affected",
"version": "5.3.4",
"versionType": "otp"
},
{
"lessThan": "11.6.0.4",
"status": "affected",
"version": "11.3",
"versionType": "otp"
},
{
"lessThan": "11.7.4",
"status": "affected",
"version": "11.7",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"tls_handshake",
"ssl_handshake",
"ssl"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"lib/ssl/src/tls_handshake.erl",
"lib/ssl/src/ssl_handshake.erl",
"lib/ssl/src/ssl.erl"
],
"programRoutines": [
{
"name": "tls_handshake:hello/5"
},
{
"name": "ssl_handshake:handle_server_hello_extensions/9"
},
{
"name": "ssl:connect/2"
},
{
"name": "ssl:connect/3"
},
{
"name": "ssl:connect/4"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "064e236414614f9085cbbbd6eacf0e43c02d1b4b",
"status": "unaffected"
},
{
"at": "0a82596d425abe43dc2e0b3d74aa1557ef74051c",
"status": "unaffected"
},
{
"at": "e6ff938116b2872bccc478af7fefb56627285b77",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "84adefa331c4159d432d22840663c38f155cd4c1",
"versionType": "git"
}
]
}
],
"configurations": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eThe vulnerability only affects TLS clients using TLS 1.2 (or earlier) or DTLS. TLS 1.3 client connections perform the cipher suite membership check and are not affected. Servers are not affected. Exploitation additionally requires an on-path (adversary-in-the-middle) attacker between the client and the intended server.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "The vulnerability only affects TLS clients using TLS 1.2 (or earlier) or DTLS. TLS 1.3 client connections perform the cipher suite membership check and are not affected. Servers are not affected. Exploitation additionally requires an on-path (adversary-in-the-middle) attacker between the client and the intended server."
}
],
"value": "The vulnerability only affects TLS clients using TLS 1.2 (or earlier) or DTLS. TLS 1.3 client connections perform the cipher suite membership check and are not affected. Servers are not affected. Exploitation additionally requires an on-path (adversary-in-the-middle) attacker between the client and the intended server."
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.15",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.4",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.4",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Jonatan M\u00e4nnchen / EEF"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Ingela Anderton Andin"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Jakub Witczak"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eThe Erlang/OTP \u003ccode\u003essl\u003c/code\u003e TLS 1.2 (and earlier) and DTLS client does not verify that the cipher suite selected by the server in \u003ccode\u003eServerHello\u003c/code\u003e was among the suites offered by the client in \u003ccode\u003eClientHello\u003c/code\u003e. The client-side \u003ccode\u003etls_handshake:hello/5\u003c/code\u003e handler validates the negotiated protocol version and the downgrade sentinel but hands the server-chosen suite directly to \u003ccode\u003essl_handshake:handle_server_hello_extensions/9\u003c/code\u003e, which installs it without a membership check. The TLS 1.3 client path performs this check (per RFC 8446), so it is not affected.\u003c/p\u003e\n\u003cp\u003eAn on-path attacker between the client and the intended server can respond with a \u003ccode\u003eServerHello\u003c/code\u003e selecting an anonymous key exchange suite such as \u003ccode\u003eTLS_DH_anon_*\u003c/code\u003e or \u003ccode\u003eTLS_ECDH_anon_*\u003c/code\u003e that the client never offered. Anonymous suites do not require the server to present a certificate, so the entire \u003ccode\u003everify_peer\u003c/code\u003e and \u003ccode\u003ecacerts\u003c/code\u003e configuration is bypassed: the attacker completes the handshake with its own ephemeral parameters, no certificate is validated, no hostname is checked, and \u003ccode\u003essl:connect\u003c/code\u003e returns \u003ccode\u003e{ok, Socket}\u003c/code\u003e. All subsequent application traffic is readable and modifiable by the attacker.\u003c/p\u003e\n\u003cp\u003eThis issue affects OTP from OTP\u0026nbsp;17.0 before OTP\u0026nbsp;27.3.4.15, from OTP\u0026nbsp;28.0 before OTP\u0026nbsp;28.5.0.4, and from OTP\u0026nbsp;29.0 before OTP\u0026nbsp;29.0.4, corresponding to ssl from 5.3.4 before 11.2.12.11, from 11.3 before 11.6.0.4, and from 11.7 before 11.7.4. Whether OTP before OTP\u0026nbsp;17.0, corresponding to ssl before 5.3.4, is affected is unknown.\u003c/p\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "The Erlang/OTP `ssl` TLS 1.2 (and earlier) and DTLS client does not verify that the cipher suite selected by the server in `ServerHello` was among the suites offered by the client in `ClientHello`. The client-side `tls_handshake:hello/5` handler validates the negotiated protocol version and the downgrade sentinel but hands the server-chosen suite directly to `ssl_handshake:handle_server_hello_extensions/9`, which installs it without a membership check. The TLS 1.3 client path performs this check (per RFC 8446), so it is not affected.\n\nAn on-path attacker between the client and the intended server can respond with a `ServerHello` selecting an anonymous key exchange suite such as `TLS_DH_anon_*` or `TLS_ECDH_anon_*` that the client never offered. Anonymous suites do not require the server to present a certificate, so the entire `verify_peer` and `cacerts` configuration is bypassed: the attacker completes the handshake with its own ephemeral parameters, no certificate is validated, no hostname is checked, and `ssl:connect` returns `{ok, Socket}`. All subsequent application traffic is readable and modifiable by the attacker.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.15, from OTP\u00a028.0 before OTP\u00a028.5.0.4, and from OTP\u00a029.0 before OTP\u00a029.0.4, corresponding to ssl from 5.3.4 before 11.2.12.11, from 11.3 before 11.6.0.4, and from 11.7 before 11.7.4. Whether OTP before OTP\u00a017.0, corresponding to ssl before 5.3.4, is affected is unknown."
}
],
"value": "The Erlang/OTP ssl TLS 1.2 (and earlier) and DTLS client does not verify that the cipher suite selected by the server in ServerHello was among the suites offered by the client in ClientHello. The client-side tls_handshake:hello/5 handler validates the negotiated protocol version and the downgrade sentinel but hands the server-chosen suite directly to ssl_handshake:handle_server_hello_extensions/9, which installs it without a membership check. The TLS 1.3 client path performs this check (per RFC 8446), so it is not affected.\n\nAn on-path attacker between the client and the intended server can respond with a ServerHello selecting an anonymous key exchange suite such as TLS_DH_anon_* or TLS_ECDH_anon_* that the client never offered. Anonymous suites do not require the server to present a certificate, so the entire verify_peer and cacerts configuration is bypassed: the attacker completes the handshake with its own ephemeral parameters, no certificate is validated, no hostname is checked, and ssl:connect returns {ok, Socket}. All subsequent application traffic is readable and modifiable by the attacker.\n\nThis issue affects OTP from OTP\u00a017.0 before OTP\u00a027.3.4.15, from OTP\u00a028.0 before OTP\u00a028.5.0.4, and from OTP\u00a029.0 before OTP\u00a029.0.4, corresponding to ssl from 5.3.4 before 11.2.12.11, from 11.3 before 11.6.0.4, and from 11.7 before 11.7.4. Whether OTP before OTP\u00a017.0, corresponding to ssl before 5.3.4, is affected is unknown."
}
],
"impacts": [
{
"capecId": "CAPEC-94",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-94 Adversary in the Middle (AiTM)"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"Automatable": "NOT_DEFINED",
"Recovery": "NOT_DEFINED",
"Safety": "NOT_DEFINED",
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 9.1,
"baseSeverity": "CRITICAL",
"privilegesRequired": "NONE",
"providerUrgency": "NOT_DEFINED",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"valueDensity": "NOT_DEFINED",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "NONE",
"vulnConfidentialityImpact": "HIGH",
"vulnIntegrityImpact": "HIGH",
"vulnerabilityResponseEffort": "NOT_DEFINED"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-757",
"description": "CWE-757 Selection of Less-Secure Algorithm During Negotiation (\u0027Algorithm Downgrade\u0027)",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-09-08T01:06:57.579Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-c6cw-pr89-w882"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-55953.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-55953"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/064e236414614f9085cbbbd6eacf0e43c02d1b4b"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/0a82596d425abe43dc2e0b3d74aa1557ef74051c"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/e6ff938116b2872bccc478af7fefb56627285b77"
}
],
"source": {
"discovery": "INTERNAL"
},
"title": "TLS 1.2 and DTLS client accepts unoffered anonymous cipher suite, bypassing server authentication",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cul\u003e\n\u003cli\u003eRestrict client connections to TLS 1.3 only by setting \u003ccode\u003eversions\u003c/code\u003e to \u003ccode\u003e[\u0027tlsv1.3\u0027]\u003c/code\u003e in the client\u0027s \u003ccode\u003essl\u003c/code\u003e options. The TLS 1.3 client path performs the required cipher suite membership check and is not affected.\u003c/li\u003e\n\u003c/ul\u003e"
},
{
"base64": false,
"type": "text/markdown",
"value": "- Restrict client connections to TLS 1.3 only by setting `versions` to `[\u0027tlsv1.3\u0027]` in the client\u0027s `ssl` options. The TLS 1.3 client path performs the required cipher suite membership check and is not affected."
}
],
"value": "* Restrict client connections to TLS 1.3 only by setting versions to [\u0027tlsv1.3\u0027] in the client\u0027s ssl options. The TLS 1.3 client path performs the required cipher suite membership check and is not affected."
}
]
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-55953",
"datePublished": "2026-07-27T15:21:29.327Z",
"dateReserved": "2026-06-17T17:55:15.686Z",
"dateUpdated": "2026-09-08T01:06:57.579Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-55737 (GCVE-0-2026-55737)
Vulnerability from nvd – Published: 2026-07-27 15:13 – Updated: 2026-07-28 09:55
VLAI
EPSS
VEX
Title
Heap pointer corruption via signed/unsigned mismatch in LARGE_TUPLE_EXT decoding in erts external term format decoder
Summary
Signed to Unsigned Conversion Error and Out-of-bounds Write vulnerability in Erlang OTP erts allows an attacker who can supply a crafted Erlang external term format (ETF) binary to binary_to_term/1 to corrupt the BEAM heap pointer and crash the virtual machine.
When decoding a LARGE_TUPLE_EXT term, the validation pass decoded_size() in erts/emulator/beam/external.c reads the 32-bit arity field as unsigned (get_uint32()), while the decode pass dec_term() reads the same field as a signed 32-bit integer (get_int32()) into an int. An arity wire value of 0x80000000 passes validation as 2147483648 but decodes as -2147483648, so the subsequent hp += n moves the heap allocation pointer backward. Neither pass enforces the runtime tuple-arity limit MAX_ARITYVAL. The result is an out-of-bounds heap write; in practice the VM detects an impossible heap size and aborts, denying service. The required padding is large when uncompressed but the compressed-ETF envelope shrinks it to a small payload on the wire.
This issue affects OTP from OTP 25.0 before OTP 29.0.4, OTP 28.5.0.4 and OTP 27.3.4.15, corresponding to erts from 13.0 before 17.0.4, 16.4.0.4 and 15.2.7.11.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-07-27 18:34 UTC
Assigner
References
5 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-55737.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-55737 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/c5210b42a9d3… | patch |
Impacted products
2 products
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-55737",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-27T18:34:45.698069Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-07-27T18:34:55.080Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"erlang",
"external"
],
"packageName": "erts",
"packageURL": "pkg:otp/erts?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Fotp\u0026vcs_url=git%20https:%2F%2Fgithub.com%2Ferlang%2Fotp.git",
"product": "OTP",
"programFiles": [
"emulator/beam/external.c"
],
"programRoutines": [
{
"name": "erlang:binary_to_term/1"
},
{
"name": "erlang:binary_to_term/2"
},
{
"name": "dec_term"
},
{
"name": "decoded_size"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "17.0.4",
"status": "unaffected"
},
{
"at": "16.4.0.4",
"status": "unaffected"
},
{
"at": "15.2.7.11",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "13.0",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"erlang",
"external"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"erts/emulator/beam/external.c"
],
"programRoutines": [
{
"name": "erlang:binary_to_term/1"
},
{
"name": "erlang:binary_to_term/2"
},
{
"name": "dec_term"
},
{
"name": "decoded_size"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "29.0.4",
"status": "unaffected"
},
{
"at": "28.5.0.4",
"status": "unaffected"
},
{
"at": "27.3.4.15",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "25.0",
"versionType": "otp"
},
{
"lessThan": "c5210b42a9d3d96f3d25601942ce8122be0f3761",
"status": "affected",
"version": "ebcbb97b4ec223464cac3d94375739a248ddef6e",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.15",
"versionStartIncluding": "25.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.4",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.4",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Nick Gunn"
},
{
"lang": "en",
"type": "remediation developer",
"value": "Kiko Fernandez-Reyes"
},
{
"lang": "en",
"type": "remediation reviewer",
"value": "Sverker Eriksson"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eSigned to Unsigned Conversion Error and Out-of-bounds Write vulnerability in Erlang OTP \u003ctt\u003eerts\u003c/tt\u003e allows an attacker who can supply a crafted Erlang external term format (ETF) binary to \u003ctt\u003ebinary_to_term/1\u003c/tt\u003e to corrupt the BEAM heap pointer and crash the virtual machine.\u003c/p\u003e\u003cp\u003eWhen decoding a \u003ctt\u003eLARGE_TUPLE_EXT\u003c/tt\u003e term, the validation pass \u003ctt\u003edecoded_size()\u003c/tt\u003e in \u003ctt\u003eerts/emulator/beam/external.c\u003c/tt\u003e reads the 32-bit arity field as unsigned (\u003ctt\u003eget_uint32()\u003c/tt\u003e), while the decode pass \u003ctt\u003edec_term()\u003c/tt\u003e reads the same field as a signed 32-bit integer (\u003ctt\u003eget_int32()\u003c/tt\u003e) into an \u003ctt\u003eint\u003c/tt\u003e. An arity wire value of \u003ctt\u003e0x80000000\u003c/tt\u003e passes validation as 2147483648 but decodes as -2147483648, so the subsequent \u003ctt\u003ehp += n\u003c/tt\u003e moves the heap allocation pointer backward. Neither pass enforces the runtime tuple-arity limit \u003ctt\u003eMAX_ARITYVAL\u003c/tt\u003e. The result is an out-of-bounds heap write; in practice the VM detects an impossible heap size and aborts, denying service. The required padding is large when uncompressed but the compressed-ETF envelope shrinks it to a small payload on the wire.\u003c/p\u003e\u003cp\u003eThis issue affects OTP from OTP 25.0 before OTP\u0026nbsp;29.0.4, OTP\u0026nbsp;28.5.0.4 and OTP\u0026nbsp;27.3.4.15, corresponding to \u003ctt\u003eerts\u003c/tt\u003e from 13.0 before 17.0.4, 16.4.0.4 and 15.2.7.11.\u003c/p\u003e"
}
],
"value": "Signed to Unsigned Conversion Error and Out-of-bounds Write vulnerability in Erlang OTP erts allows an attacker who can supply a crafted Erlang external term format (ETF) binary to binary_to_term/1 to corrupt the BEAM heap pointer and crash the virtual machine.\n\nWhen decoding a LARGE_TUPLE_EXT term, the validation pass decoded_size() in erts/emulator/beam/external.c reads the 32-bit arity field as unsigned (get_uint32()), while the decode pass dec_term() reads the same field as a signed 32-bit integer (get_int32()) into an int. An arity wire value of 0x80000000 passes validation as 2147483648 but decodes as -2147483648, so the subsequent hp += n moves the heap allocation pointer backward. Neither pass enforces the runtime tuple-arity limit MAX_ARITYVAL. The result is an out-of-bounds heap write; in practice the VM detects an impossible heap size and aborts, denying service. The required padding is large when uncompressed but the compressed-ETF envelope shrinks it to a small payload on the wire.\n\nThis issue affects OTP from OTP 25.0 before OTP\u00a029.0.4, OTP\u00a028.5.0.4 and OTP\u00a027.3.4.15, corresponding to erts from 13.0 before 17.0.4, 16.4.0.4 and 15.2.7.11."
}
],
"impacts": [
{
"capecId": "CAPEC-92",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-92 Forced Integer Overflow"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"attackComplexity": "LOW",
"attackRequirements": "NONE",
"attackVector": "LOCAL",
"baseScore": 5.1,
"baseSeverity": "MEDIUM",
"privilegesRequired": "NONE",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"vectorString": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "LOW",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-195",
"description": "CWE-195 Signed to Unsigned Conversion Error",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-787",
"description": "CWE-787 Out-of-bounds Write",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-07-28T09:55:26.434Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-446w-268v-9462"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-55737.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-55737"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/c5210b42a9d3d96f3d25601942ce8122be0f3761"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "Heap pointer corruption via signed/unsigned mismatch in LARGE_TUPLE_EXT decoding in erts external term format decoder",
"x_generator": {
"engine": "cvelib 1.8.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-55737",
"datePublished": "2026-07-27T15:13:54.699Z",
"dateReserved": "2026-06-17T10:44:34.365Z",
"dateUpdated": "2026-07-28T09:55:26.434Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
CVE-2026-54890 (GCVE-0-2026-54890)
Vulnerability from nvd – Published: 2026-07-27 15:39 – Updated: 2026-07-28 09:55
VLAI
EPSS
VEX
Title
BEAM VM crash via integer underflow in binary_to_term BIT_BINARY_EXT decoding
Summary
Integer Underflow (Wrap or Wraparound) vulnerability in erlang otp erlang/otp (erts modules), erlang otp erts (erts modules) allows Forced Integer Overflow, Excessive Allocation. This vulnerability is associated with program files erts/emulator/beam/external.c, emulator/beam/external.c.
The BIT_BINARY_EXT tag (77) handler in the External Term Format (ETF) decoder accepts an encoding with both length and trailing-bits fields set to zero. The subsequent computation of the bitstring size underflows an unsigned integer, producing a value of roughly 2^64 that is then passed as a memory allocation size. The allocator aborts the entire node with a message such as "Cannot allocate 2305843009213693951 bytes of memory (of type binary)".
The crash is a VM-level abort, not an Erlang-level exception. It cannot be intercepted by supervision trees, by try/catch, or by passing the [safe] option to binary_to_term/2 (which only restricts atom creation and does not perform structural validation of binary encodings).
Any application that decodes ETF from untrusted sources via binary_to_term/1,2 or enif_binary_to_term() is exposed. The Erlang distribution protocol also decodes incoming terms through the same code path, but distribution is expected to run on trusted networks per the OTP Secure Coding Guidelines (DSG-011).
This issue affects OTP from OTP 27.0 before OTP 29.0.4, OTP 28.5.0.4 and OTP 27.3.4.15, corresponding to erts from 15.0 before 17.0.4, 16.4.0.4 and 15.2.7.11.
Severity
SSVC
Exploitation: none
Automatable: no
Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-07-27 18:18 UTC
CWE
Assigner
References
5 references
| URL | Tags |
|---|---|
| https://github.com/erlang/otp/security/advisories… | vendor-advisoryrelated |
| https://cna.erlef.org/cves/CVE-2026-54890.html | related |
| https://osv.dev/vulnerability/EEF-CVE-2026-54890 | related |
| https://www.erlang.org/doc/system/versions.html#o… | x_version-scheme |
| https://github.com/erlang/otp/commit/dc1bf9344c0c… | patch |
Impacted products
2 products
{
"containers": {
"adp": [
{
"metrics": [
{
"other": {
"content": {
"id": "CVE-2026-54890",
"options": [
{
"Exploitation": "none"
},
{
"Automatable": "no"
},
{
"Technical Impact": "partial"
}
],
"role": "CISA Coordinator",
"timestamp": "2026-07-27T18:18:57.223218Z",
"version": "2.0.3"
},
"type": "ssvc"
}
}
],
"providerMetadata": {
"dateUpdated": "2026-07-27T18:19:08.876Z",
"orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"shortName": "CISA-ADP"
},
"title": "CISA ADP Vulnrichment"
}
],
"cna": {
"affected": [
{
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"erts"
],
"packageName": "erts",
"packageURL": "pkg:otp/erts?repository_url=https:%2F%2Fgithub.com%2Ferlang%2Fotp\u0026vcs_url=git%20https:%2F%2Fgithub.com%2Ferlang%2Fotp.git",
"product": "OTP",
"programFiles": [
"emulator/beam/external.c"
],
"programRoutines": [
{
"name": "erlang:binary_to_term/1"
},
{
"name": "erlang:binary_to_term/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "15.2.7.11",
"status": "unaffected"
},
{
"at": "16.4.0.4",
"status": "unaffected"
},
{
"at": "17.0.4",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "15.0",
"versionType": "otp"
}
]
},
{
"collectionURL": "https://github.com",
"cpes": [
"cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"
],
"defaultStatus": "unaffected",
"modules": [
"erts"
],
"packageName": "erlang/otp",
"packageURL": "pkg:github/erlang/otp",
"product": "OTP",
"programFiles": [
"erts/emulator/beam/external.c"
],
"programRoutines": [
{
"name": "erlang:binary_to_term/1"
},
{
"name": "erlang:binary_to_term/2"
}
],
"repo": "https://github.com/erlang/otp",
"vendor": "Erlang",
"versions": [
{
"changes": [
{
"at": "27.3.4.15",
"status": "unaffected"
},
{
"at": "28.5.0.4",
"status": "unaffected"
},
{
"at": "29.0.4",
"status": "unaffected"
}
],
"lessThan": "*",
"status": "affected",
"version": "27.0",
"versionType": "otp"
},
{
"lessThan": "dc1bf9344c0ce62717cf60866590cea0242780fd",
"status": "affected",
"version": "24ef4cbaeda9b9c26682cba75f2f15b0c58722aa",
"versionType": "git"
}
]
}
],
"cpeApplicability": [
{
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "27.3.4.15",
"versionStartIncluding": "27.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "28.5.0.4",
"versionStartIncluding": "28.0",
"vulnerable": true
},
{
"criteria": "cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*",
"versionEndExcluding": "29.0.4",
"versionStartIncluding": "29.0",
"vulnerable": true
}
],
"negate": false,
"operator": "OR"
}
],
"operator": "AND"
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "Paul Guyot"
},
{
"lang": "en",
"type": "finder",
"value": "Lukas Backstr\u00f6m"
},
{
"lang": "en",
"type": "remediation developer",
"value": "John H\u00f6gberg"
}
],
"descriptions": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "Integer Underflow (Wrap or Wraparound) vulnerability in erlang otp erlang/otp (erts modules), erlang otp erts (erts modules) allows Forced Integer Overflow, Excessive Allocation. This vulnerability is associated with program files \u003ctt\u003eerts/emulator/beam/external.c\u003c/tt\u003e, \u003ctt\u003eemulator/beam/external.c\u003c/tt\u003e.\u003cp\u003eThe \u003ctt\u003eBIT_BINARY_EXT\u003c/tt\u003e tag (77) handler in the External Term Format (ETF) decoder accepts an encoding with both length and trailing-bits fields set to zero. The subsequent computation of the bitstring size underflows an unsigned integer, producing a value of roughly 2^64 that is then passed as a memory allocation size. The allocator aborts the entire node with a message such as \u003ctt\u003eCannot allocate 2305843009213693951 bytes of memory (of type \"binary\")\u003c/tt\u003e.\u003c/p\u003e\u003cp\u003eThe crash is a VM-level abort, not an Erlang-level exception. It cannot be intercepted by supervision trees, by \u003ctt\u003etry\u003c/tt\u003e/\u003ctt\u003ecatch\u003c/tt\u003e, or by passing the \u003ctt\u003e[safe]\u003c/tt\u003e option to \u003ctt\u003ebinary_to_term/2\u003c/tt\u003e (which only restricts atom creation and does not perform structural validation of binary encodings).\u003c/p\u003e\u003cp\u003eAny application that decodes ETF from untrusted sources via \u003ctt\u003ebinary_to_term/1,2\u003c/tt\u003e or \u003ctt\u003eenif_binary_to_term()\u003c/tt\u003e is exposed. The Erlang distribution protocol also decodes incoming terms through the same code path, but distribution is expected to run on trusted networks per the OTP Secure Coding Guidelines (DSG-011).\u003c/p\u003e\u003cp\u003eThis issue affects OTP from OTP 27.0 before OTP\u0026nbsp;29.0.4, OTP\u0026nbsp;28.5.0.4 and OTP\u0026nbsp;27.3.4.15, corresponding to erts from 15.0 before 17.0.4, 16.4.0.4 and 15.2.7.11.\u003c/p\u003e"
}
],
"value": "Integer Underflow (Wrap or Wraparound) vulnerability in erlang otp erlang/otp (erts modules), erlang otp erts (erts modules) allows Forced Integer Overflow, Excessive Allocation. This vulnerability is associated with program files erts/emulator/beam/external.c, emulator/beam/external.c.\n\nThe BIT_BINARY_EXT tag (77) handler in the External Term Format (ETF) decoder accepts an encoding with both length and trailing-bits fields set to zero. The subsequent computation of the bitstring size underflows an unsigned integer, producing a value of roughly 2^64 that is then passed as a memory allocation size. The allocator aborts the entire node with a message such as \"Cannot allocate 2305843009213693951 bytes of memory (of type binary)\".\n\nThe crash is a VM-level abort, not an Erlang-level exception. It cannot be intercepted by supervision trees, by try/catch, or by passing the [safe] option to binary_to_term/2 (which only restricts atom creation and does not perform structural validation of binary encodings).\n\nAny application that decodes ETF from untrusted sources via binary_to_term/1,2 or enif_binary_to_term() is exposed. The Erlang distribution protocol also decodes incoming terms through the same code path, but distribution is expected to run on trusted networks per the OTP Secure Coding Guidelines (DSG-011).\n\nThis issue affects OTP from OTP 27.0 before OTP\u00a029.0.4, OTP\u00a028.5.0.4 and OTP\u00a027.3.4.15, corresponding to erts from 15.0 before 17.0.4, 16.4.0.4 and 15.2.7.11."
}
],
"impacts": [
{
"capecId": "CAPEC-92",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-92 Forced Integer Overflow"
}
]
},
{
"capecId": "CAPEC-130",
"descriptions": [
{
"lang": "en",
"value": "CAPEC-130 Excessive Allocation"
}
]
}
],
"metrics": [
{
"cvssV4_0": {
"attackComplexity": "LOW",
"attackRequirements": "PRESENT",
"attackVector": "NETWORK",
"baseScore": 8.2,
"baseSeverity": "HIGH",
"privilegesRequired": "NONE",
"subAvailabilityImpact": "NONE",
"subConfidentialityImpact": "NONE",
"subIntegrityImpact": "NONE",
"userInteraction": "NONE",
"vectorString": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
"version": "4.0",
"vulnAvailabilityImpact": "HIGH",
"vulnConfidentialityImpact": "NONE",
"vulnIntegrityImpact": "NONE"
},
"format": "CVSS",
"scenarios": [
{
"lang": "en",
"value": "GENERAL"
}
]
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-191",
"description": "CWE-191 Integer Underflow (Wrap or Wraparound)",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-789",
"description": "CWE-789 Memory Allocation with Excessive Size Value",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-1284",
"description": "CWE-1284 Improper Validation of Specified Quantity in Input",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-07-28T09:55:08.138Z",
"orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"shortName": "EEF"
},
"references": [
{
"tags": [
"vendor-advisory",
"related"
],
"url": "https://github.com/erlang/otp/security/advisories/GHSA-54pw-5645-jh86"
},
{
"tags": [
"related"
],
"url": "https://cna.erlef.org/cves/CVE-2026-54890.html"
},
{
"tags": [
"related"
],
"url": "https://osv.dev/vulnerability/EEF-CVE-2026-54890"
},
{
"tags": [
"x_version-scheme"
],
"url": "https://www.erlang.org/doc/system/versions.html#order-of-versions"
},
{
"tags": [
"patch"
],
"url": "https://github.com/erlang/otp/commit/dc1bf9344c0ce62717cf60866590cea0242780fd"
}
],
"source": {
"discovery": "EXTERNAL"
},
"title": "BEAM VM crash via integer underflow in binary_to_term BIT_BINARY_EXT decoding",
"workarounds": [
{
"lang": "en",
"supportingMedia": [
{
"base64": false,
"type": "text/html",
"value": "\u003cp\u003eDo not call \u003ctt\u003ebinary_to_term/1,2\u003c/tt\u003e or \u003ctt\u003eenif_binary_to_term()\u003c/tt\u003e on data from untrusted sources. The OTP Secure Coding Guidelines (DSG-011) recommend avoiding these functions altogether on untrusted input and using an alternative serialization format (for example JSON or Protocol Buffers) instead.\u003c/p\u003e"
}
],
"value": "Do not call binary_to_term/1,2 or enif_binary_to_term() on data from untrusted sources. The OTP Secure Coding Guidelines (DSG-011) recommend avoiding these functions altogether on untrusted input and using an alternative serialization format (for example JSON or Protocol Buffers) instead."
}
],
"x_generator": {
"engine": "cvelib 1.8.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
"assignerShortName": "EEF",
"cveId": "CVE-2026-54890",
"datePublished": "2026-07-27T15:39:03.475Z",
"dateReserved": "2026-06-16T10:47:13.915Z",
"dateUpdated": "2026-07-28T09:55:08.138Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}