CVE-2026-54890
Executive Summary
CVE-2026-54890 is a remote denial-of-service (DoS) vulnerability in the Erlang/OTP BEAM virtual machine's External Term Format (ETF) decoder, specifically within the binary_to_term/1,2 and enif_binary_to_term() functions. An unauthenticated attacker who can supply crafted binary data to an Erlang application—or who can send malicious messages over an unauthenticated Erlang distribution channel—can trigger an integer underflow in the BIT_BINARY_EXT tag handler, causing the VM to attempt an enormous memory allocation and abort the entire node. This results in a complete denial of service for all applications hosted on that node, and the crash is not recoverable via supervision trees or try/catch. Affected versions include all OTP releases from 27.0 through 29.0.x prior to the patched releases; the issue is resolved in OTP 29.0.5, OTP 28.5.0.4, and OTP 27.3.4.15.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The vulnerability resides in the External Term Format (ETF) decoder implemented in erts/emulator/beam/external.c. ETF is the binary serialization format used by Erlang for term interchange, and it is parsed by binary_to_term/1,2. The decoder handles a sequence of tag bytes; tag 77 (BIT_BINARY_EXT) represents a bitstring (a binary with a partial trailing byte).
In the ETF specification, a BIT_BINARY_EXT encoding has the following structure:
77 | Len (4 bytes, unsigned 32-bit) | Bits (1 byte) | Data (ceil(Len * 8 / Bits) bytes)
The Len field specifies the number of bits, and the Bits field specifies how many of the bits in the final byte are significant (1–8). The handler computes the required byte size using logic similar to:
size = (Len / 8) + ((Len % 8) ? 1 : 0);
However, the vulnerable code path uses a different arithmetic when Bits is involved, specifically when both Len == 0 and Bits == 0. In the bitstring allocation routine, the code computes the full size in bits and then converts to bytes. When both fields are zero, the size calculation wraps around an unsigned 64-bit integer (CWE-191: Integer Underflow), producing a value of approximately 2^64 - 1 bits. This value is converted to bytes (~`2305843009213693951` bytes) and passed to the memory allocator.
The allocator fails to reserve that block and terminates the BEAM process with a fatal error message such as:
Cannot allocate 2305843009213693951 bytes of memory (of type binary)
This is a VM-level abort (e.g., erl_crash.dump is written, the node stops), not a catchable Erlang exception. Neither try/catch nor the [safe] option of binary_to_term/2 (which only restricts atom creation) prevents the crash.
Attack Surface:
The primary attack surface is any application that invokes binary_to_term/1,2 or enif_binary_to_term() on externally supplied data (e.g., network payloads, uploaded files, database blobs). Additionally, the Erlang distribution protocol (used for inter-node communication) internally calls the same decoder. If distribution is enabled with the default cookie—or with a weak/leaked cookie, or on an exposed port—a remote attacker can send a malformed term that will be decoded at the receiving node, causing the crash. The OTP Secure Coding Guidelines (DSG-011) explicitly state that binary_to_term must not be used on untrusted input; this CVE reinforces that directive.
The underlying cause is a failure to validate that Bits >= 1 and that Len > 0 when Bits == 0. A strict validation pass in the BIT_BINARY_EXT handler before any arithmetic would prevent the underflow.
Exploitation Scenarios
Scenario 1: Remote exploitation via an unauthenticated Erlang distribution endpoint
Reconnaissance: The attacker scans the internet for hosts exposing the Erlang Port Mapper Daemon (EPMD) on TCP port 4369, or for nodes advertising their distribution listener on ports in the 4370–4400 range. A Shodan query such as
port:4369or"Erlang Port Mapper Daemon"may reveal such nodes. The attacker also probes for the node's cookie by attempting a few common defaults (cookie,abc,secret) or by sniffing it from a misconfigured application.Weaponization: The attacker constructs a raw ETF binary with tag
77(BIT_BINARY_EXT), followed by a 4-byte little-endian length of0x00000000and a single byte of0x00for the trailing-bits field. The full payload is just six bytes:\x4D\x00\x00\x00\x00\x00.Delivery/Exploitation: If the attacker knows the node name and cookie, they can establish a distribution connection directly. Alternatively, they can inject the malformed binary as the payload of a standard distribution message (e.g., using the
!send operation) to the target node. When the receiving node decodes the message term, theBIT_BINARY_EXThandler underflows and attempts to allocate2305843009213693951bytes.Post-exploitation impact: The BEAM VM aborts. All processes, applications, and network listeners on that node die instantly. Any connected clients lose service, and unless a supervisor automatically restarts the node (which is non-trivial with
-heart), the service remains down, enabling repeated single-packet DoS attacks.
Scenario 2: Application-level exploitation via binary_to_term on untrusted input
Target identification: The attacker finds a web application or network protocol handler that accepts a base64-encoded or raw binary blob and passes it to
binary_to_term/1without sanitization.Trigger: The attacker submits a crafted payload: the byte sequence
\x4D\x00\x00\x00\x00\x00(possibly base64-encoded asTQAAAAA=).Execution: The application calls
binary_to_term(Binary). The VM aborts, crashing the entire node, not just the handling process.Post-exploitation: The service becomes unavailable. An attacker can repeat this indefinitely, and because the crash occurs before any Erlang-level handling, there is no exception handling that can save the node.
Impact Assessment
CIA Impact: The vulnerability has no direct confidentiality or integrity impact—an attacker cannot read or modify data. The sole impact is availability: the target node crashes entirely.
CVSS: The official NVD score is listed as N/A (the CVE record lacks a vector). For risk prioritization, we assess this with a conservative network-based vector: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H — a score of 5.9 (Medium). The high attack complexity reflects the requirement that the target node must be running Erlang distribution on an untrusted network or accepting binary_to_term on attacker-controlled input, which is a guideline-goto violation.
Business Blast Radius: For a single-node deployment, the blast radius is that single service. For clustered Erlang systems (common in telecommunications, messaging, and financial trading), a crash on one node can cascade: other nodes may wait for a response until timeouts occur, leading to cluster-wide degradation or split-brain situations. Because binary_to_term is frequently used in data ingestion pipelines (e.g., decoding messages from queues), a targeted crash can act as a precursor to further reconnaissance or to mask other malicious activity.
EPSS: The EPSS score is 0.00318 (24.3rd percentile), indicating low near-term real-world exploitation probability. However, the simplicity of the payload—six bytes that do not require authentication on many systems—could drive a spike if threat actors begin probing for exposed Erlang nodes. The existence of a patch (claimed by OSV but not independently confirmed) lowers the urgency, but the lack of a CISA KEV entry means there is no formal government-mandated remediation deadline.
Detection Guidance
Sigma Rule
title: Potential Erlang BEAM VM Crash via Malformed ETF (CVE-2026-54890)
id: 05c2f8e4-9b4e-4c1e-8e1a-4f9b3f2b6e4a
status: experimental
description: Detects application logs indicating an Erlang memory allocation failure with a size indicative of BIT_BINARY_EXT underflow.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-54890
date: 2026/05/14
tags:
- attack.t1499
- cve.2026.54890
author: Valtersit SOC
logsource:
category: application
product: erlang
definition: 'Requires Erlang error_logger or crash dumps being forwarded as application logs.'
detection:
selection_memory:
message|contains|all:
- 'Cannot allocate'
- 'bytes of memory (of type binary)'
selection_size:
message|contains:
- '2305843009213693951'
- '9223372036854775807'
condition: selection_memory and selection_size
falsepositives:
- Legitimate attempts to allocate >2^63 bytes (extremely unlikely).
level: high
YARA Rule
rule Erlang_CVE_2026_54890_BIT_BINARY_EXT_Payload
{
meta:
author = "Valtersit SOC"
description = "Detects the exact six-byte ETF bitstring payload that triggers the BIT_BINARY_EXT integer underflow in Erlang/OTP BEAM VM."
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-54890"
date = "2026-05-14"
strings:
$bit_binary_payload = { 4D 00 00 00 00 00 }
$bit_binary_var = { 4D 00 00 00 00 [00-08] }
condition:
any of them
}
Suricata IDS Rule
alert tcp any any -> any any (msg:"ET EXPLOIT Erlang BIT_BINARY_EXT Zero-Length Underflow Attempt (CVE-2026-54890)"; flow:to_server; content:"|4d 00 00 00 00 00|"; depth:6; reference:cve,2026-54890; classtype:attempted-dos; sid:30000001; rev:1;)
Elastic Detection
process where event.type == "start"
and process.name in ("beam.smp", "erl.exe", "beam")
and process.args : ("*crash*", "*-heart*")
and (process.parent.command_line : "*Cannot allocate*"
or process.command_line : "*Cannot allocate*")
Alternative EQL based on logs:
logs-* / error_logger {
message: "*Cannot allocate 2305843009213693951 bytes of memory*"
}
Splunk SPL Query
index="main" sourcetype="erlang:error"
message="*Cannot allocate*bytes of memory*"
| rex field=message "Cannot allocate (?<alloc_size>\d+) bytes"
| where alloc_size >= 9223372036854775807
| table _time, host, source, process_name, alloc_size
| sort - _time
Wazuh OSSEC Rule
<group name="erlang,">
<rule id="100501" level="12">
<decoded>Cannot allocate \d+ bytes of memory \(of type binary\)</decoded>
<field name="alloc_size">>9223372036854775807</field>
<description>Erlang BEAM VM memory allocation failure - possible CVE-2026-54890 exploitation attempt</description>
<group>dos, erlang, cve-2026-54890,</group>
<mitre><id>T1499</id></mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch Confidence: 2/4 (CLAIMED — single source claims patch (not independently confirmed)). The OSV database lists fixed commits, but no vendor advisory has been publicly cross-confirmed; treat patch availability with acknowledged uncertainty.
1. Immediate Mitigations (no downtime required):
- Block untrusted ETF decoding: Audit all call sites of
binary_to_term/1,2andenif_binary_to_term(). If data originates from the network, a file upload, or a message queue fed by external parties, replace the call with a safe decoder (e.g.,term_to_binary/1round-trip validation after parsing, or switch to JSON/Protocol Buffers). - Harden the distribution protocol: Ensure Erlang distribution is disabled entirely (
-kernel inet_dist_listen_min 99999), or restrict it to trusted IP ranges via firewall rules. Change node cookies to strong, random values and never use the defaultnocookie. Consider setting-kernel dist_auto_connect false. - Rate-limit connections to the distribution port to slow repeated crash attempts, though this does not prevent a single-packet crash.
2. Patch/Upgrade Steps (requires node restart):
- Upgrade to OTP 29.0.5 (the first 29.0.x release with the fix).
- If running OTP 28.x, upgrade to OTP 28.5.0.4.
- If running OTP 27.x, upgrade to OTP 27.3.4.15.
- These correspond to erts versions 17.0.4 (OTP 29), 16.4.0.4 (OTP 28), and 15.2.7.11 (OTP 27).
- After patching, run the regression test by submitting the six-byte payload
\x4D\x00\x00\x00\x00\x00to a test node; a patched node should raise an Erlang-levelbadargexception or ignore the malformed term rather than crashing.
3. Long-term Hardening:
- Enforce the OTP Secure Coding Guidelines (DSG-011) in your development lifecycle via static analysis tools that flag all uses of
binary_to_termon non-literal data. - For any externally facing service, deploy a reverse proxy or protocol gateway that validates message framing and rejects binary payloads that cannot be safely validated before they reach the BEAM VM.
- Subscribe to the OTP security mailing list and monitor the
ertschangelog for future decoder hardening patches. - Consider running distribution messages over TLS (
-proto_dist inet_tls) and placing the node behind a dedicated firewall/VPN, as the distribution protocol is an implicitly trusted channel.
References
- NVD Entry: CVE-2026-54890 — NVD — Official CVE record with affected package names (
erlang otp erts). - OSV Advisory: OSV Record for CVE-2026-54890 — Contains patch confidence 2/4 and the list of fixed commits (
601a0128…,9e6f6742…,550d7b78…). - OTP Secure Coding Guidelines: DSG-011 — Erlang/OTP Security Guidelines — Mandates that
binary_to_term/1must not be used on untrusted data; alternative serialization formats are recommended. - Erlang ETF Specification: External Term Format — erlang.org — Describes the
BIT_BINARY_EXTtag (77) structure referenced in the vulnerability. - CISA KEV Catalog: CISA Known Exploited Vulnerabilities Catalog — No KEV entry for CVE-2026-54890 as of May 14, 2026; there are no known in-the-wild campaigns reported at the time of writing, and this report reflects no confirmed active exploitation.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.