CVEReports
CVEReports

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

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-21619

Unsafe Deserialization in Erlang Hex Ecosystem (hex_core, rebar3)

Alon Barad
Alon Barad
Software Engineer

Mar 1, 2026·5 min read·37 visits

Executive Summary (TL;DR)

Vulnerable Erlang/Elixir build tools deserialize untrusted API responses using unsafe methods. An attacker controlling a package mirror or network position can inject malicious Erlang terms, causing VM crashes (DoS) or executing arbitrary code.

A critical unsafe deserialization vulnerability exists in `hex_core`, the reference implementation for the Hex package manager API, affecting downstream tools like `hex` and `rebar3`. The flaw stems from the use of the unsafe `binary_to_term/1` function when processing HTTP response bodies, allowing attackers to trigger Denial of Service via atom table exhaustion or potentially achieve Remote Code Execution through object injection.

Vulnerability Overview

The vulnerability resides in hex_core, a foundational library used by the Erlang and Elixir ecosystems to interact with the Hex package registry. Specifically, the library failed to validate serialized Erlang terms received from the Hex API before decoding them. This affects hex (the Mix package manager) and rebar3 (the Erlang build tool), meaning the vulnerability extends to the majority of build pipelines in this ecosystem.

When a client requests package information, the Hex API often returns data encoded in the Erlang External Term Format. The vulnerable code used the native binary_to_term/1 function to decode this data. This function is inherently unsafe when applied to untrusted input because it deserializes data into memory without restriction, creating atoms and other complex structures directly within the Erlang VM.

By spoofing a Hex API response—either through a compromised mirror, a Man-in-the-Middle (MitM) attack, or a malicious proxy—an attacker can supply a crafted binary payload. This payload is processed automatically by the build tool, leading to immediate resource exhaustion or the instantiation of malicious objects.

Root Cause Analysis

The root cause is the misuse of binary_to_term/1 for processing external data (CWE-502). In the Erlang Beam VM, atoms (literals used as identifiers) are stored in a non-garbage-collected global table with a fixed limit (default 1,048,576). Once created, an atom persists until the VM terminates. The binary_to_term/1 function creates new atoms if they do not already exist in the table.

Mechanism 1: Atom Table Exhaustion (DoS) An attacker can construct a payload containing hundreds of thousands of unique, random atoms. When the client deserializes this payload, the VM attempts to register all new atoms. This rapidly fills the atom table. Once the limit is reached, the Erlang VM allocates no further memory for atoms and crashes instantly, terminating the build process.

Mechanism 2: Object Injection (RCE) The Erlang External Term Format supports the serialization of anonymous functions (funs). If an attacker injects a serialized fun into the response, and the application logic subsequently invokes that term (or passes it to a function expecting a callback), the attacker's code executes within the context of the build tool. This allows for arbitrary system command execution via os:cmd/1 wrapped inside the injected function.

Code Analysis

The vulnerability existed in the HTTP response handling logic within src/hex_api.erl. The code implicitly trusted the Content-Type: application/vnd.hex+erlang header and passed the body directly to the deserializer.

Vulnerable Code (Pre-Patch):

%% src/hex_api.erl
case binary:match(ContentType, ?ERL_CONTENT_TYPE) of
    {_, _} ->
        %% CRITICAL: Unsafe deserialization of untrusted binary data
        %% This permits atom creation and function instantiation
        {ok, {Status, RespHeaders, binary_to_term(RespBody)}};
    nomatch ->
        {ok, {Status, RespHeaders, nil}}
end.

Patched Code (Post-Patch):

The fix introduces two layers of defense. First, it switches to binary_to_term/2 with the safe option, which forbids the creation of new atoms. Second, it implements a recursive validator that ensures the deserialized term only contains inert data types (lists, tuples, maps, numbers, binaries) and explicitly rejects dangerous types like fun or port.

%% src/hex_api.erl
case binary:match(ContentType, ?ERL_CONTENT_TYPE) of
    {_, _} ->
        %% FIX 1: Use the [safe] flag to prevent atom creation
        case binary_to_term(RespBody, [safe]) of
            Term ->
                %% FIX 2: Recursively validate the structure against a whitelist
                case hex_safe_binary_to_term:validate(Term) of
                    ok ->
                        {ok, {Status, RespHeaders, Term}};
                    {error, Reason} ->
                        {error, Reason}
                end;
            Error ->
                {error, Error}
        end;
    nomatch ->
        ...
end.

Exploitation Methodology

To exploit this vulnerability, an attacker requires a position in the network to modify traffic or control over a repository mirror configured by the victim. The attack does not require authentication to the victim's machine, but it does require the victim to initiate a build command (User Interaction).

  1. Interception: The attacker intercepts a request to the Hex API (e.g., during mix deps.get). If TLS validation is disabled or compromised, this is trivial. Alternatively, the attacker sets up a rogue mirror.
  2. Payload Generation: The attacker generates a malicious payload using Erlang:
    %% DoS Payload: List of 1M unique atoms
    Payload = term_to_binary([list_to_atom(integer_to_list(I)) || I <- lists:seq(1, 1000000)]).
     
    %% RCE Payload: Embedded fun
    Payload = term_to_binary(fun() -> os:cmd("rm -rf /") end).
  3. Delivery: The attacker serves this binary as the HTTP response body with the header Content-Type: application/vnd.hex+erlang.
  4. Execution: The victim's client receives the response, deserializes it, and either crashes immediately (DoS) or stores the malicious term. If the term is a fun and the client logic executes it (e.g., expecting a callback), the payload triggers.

Impact Assessment

Despite the CVSS v4.0 score of 2.0 (which heavily penalizes the Attack Requirements and User Interaction), the technical impact is critical for affected environments. Development and CI/CD pipelines are the primary targets.

  • Availability (High): The most reliable outcome is a Denial of Service. A crash in rebar3 or mix halts deployment pipelines, potentially blocking releases or causing operational downtime in automated environments.
  • Integrity & Confidentiality (High - Conditional): If the RCE vector is successfully triggered, the attacker gains the privileges of the user running the build tool. In CI/CD environments, this often equates to root access or access to sensitive secrets (API keys, signing certificates) stored in the build environment.
  • Supply Chain Risk: Compromising a developer's machine via a build tool allows an attacker to inject backdoors into the software being built, propagating the attack further downstream.

Official Patches

hexpmhex_core v0.12.1 fix commit

Fix Analysis (2)

Technical Appendix

CVSS Score
2.0/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:A/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
EPSS Probability
0.02%
Top 97% most exploited

Affected Systems

rebar3 < 3.27.0hex < 2.3.2hex_core < 0.12.1

Affected Versions Detail

Product
Affected Versions
Fixed Version
hex_core
hexpm
< 0.12.10.12.1
hex
hexpm
< 2.3.22.3.2
rebar3
erlang
< 3.27.03.27.0
AttributeDetail
CWE IDCWE-502 (Deserialization of Untrusted Data)
Secondary CWECWE-400 (Uncontrolled Resource Consumption)
Attack VectorNetwork
CVSS v4.02.0 (Low)
ImpactDoS / RCE
Exploit StatusPoC Available

MITRE ATT&CK Mapping

T1195Supply Chain Compromise
Initial Access
T1499Endpoint Denial of Service
Impact
T1059Command and Scripting Interpreter
Execution
CWE-502
Deserialization of Untrusted Data

The application deserializes untrusted data without sufficiently verifying that the resulting data will be valid.

Known Exploits & Detection

GitHub AdvisoryVendor advisory describing atom exhaustion and object injection vectors.

Vulnerability Timeline

Fix committed to hex_core and hex
2026-02-27
rebar3 v3.27.0 released with fix
2026-02-27
CVE-2026-21619 Published
2026-02-27

References & Sources

  • [1]GHSA-hx9w-f2w9-9g96: Unsafe Deserialization in hex_core
  • [2]Erlang Documentation: binary_to_term/1

Attack Flow Diagram

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

More Reports

•about 6 hours ago•GHSA-PW6J-QG29-8W7F
5.9

GHSA-pw6j-qg29-8w7f: State Persistence and Sensitive Credential Leakage in Tornado CurlAsyncHTTPClient

A state persistence vulnerability exists in Tornado's CurlAsyncHTTPClient component where pooled pycurl.Curl handles are reused across asynchronous requests without a complete state reset. Consequently, sensitive per-request configurations, such as client TLS certificates or proxy basic authentication credentials, persist on the shared handle. This behavior leads to subsequent requests leaking these credentials to unauthorized remote servers.

Amit Schendel
Amit Schendel
3 views•7 min read
•about 6 hours ago•CVE-2026-48748
7.5

CVE-2026-48748: Netty HTTP/3 QPACK Blocked Streams Memory Exhaustion

CVE-2026-48748 is a denial-of-service vulnerability in Netty's HTTP/3 codec (netty-codec-http3) occurring when QPACK dynamic tables are enabled but the blocked streams limit is not explicitly configured. A bug in limit checking and a memory leak in stream tracking allow unauthenticated remote attackers to exhaust the JVM heap memory and crash the server.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 7 hours ago•CVE-2026-50009
4.8

CVE-2026-50009: Stateless Reset Token Exposure in Netty QUIC

CVE-2026-50009 is a cryptographic design vulnerability in the Netty network application framework. Prior to version 4.2.15.Final, the framework's QUIC protocol implementation fails to cryptographically segregate the generated Connection IDs and the associated Stateless Reset Tokens. An on-path network attacker who sniffs traffic during a Connection ID rotation can extract secret token material from cleartext headers, enabling them to inject spoofed reset packets and terminate active connections.

Alon Barad
Alon Barad
5 views•6 min read
•about 7 hours ago•CVE-2026-50010
7.5

CVE-2026-50010: Hostname Verification Bypass in Netty TLS Client

A critical hostname verification bypass vulnerability exists in the Netty network application framework when configured as a TLS client. When a developer registers a custom plain X509TrustManager, Netty wraps it inside an X509TrustManagerWrapper to adapt it to the X509ExtendedTrustManager API. However, this wrapper discards the SSLEngine context, bypassing critical hostname checks. Because the wrapper is identified as an X509ExtendedTrustManager, standard cryptographic engines and Netty's OpenSSL wrappers do not re-wrap it, failing to execute any hostname validation. Consequently, clients silently accept certificates for any host, enabling unauthenticated Man-in-the-Middle (MitM) attacks.

Amit Schendel
Amit Schendel
5 views•8 min read
•about 8 hours ago•CVE-2026-50011
7.5

CVE-2026-50011: Unbounded Resource Pre-Allocation in Netty Redis Codec

An uncontrolled resource pre-allocation flaw in the Netty Redis codec module allows remote unauthenticated attackers to cause a denial of service (OutOfMemoryError) by sending a crafted Redis Serialization Protocol (RESP) array header.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 8 hours ago•CVE-2026-50020
5.3

CVE-2026-50020: HTTP Request Smuggling in Netty HttpObjectDecoder via Arbitrary Leading Control Bytes

CVE-2026-50020 is a medium-severity HTTP Request Smuggling/Response Smuggling vulnerability (CWE-444) within the Netty asynchronous network application framework. The flaw resides in Netty's HTTP codec implementation, specifically the HttpObjectDecoder class, which silently consumes arbitrary ISO control bytes preceding the first request line.

Alon Barad
Alon Barad
4 views•7 min read