May 14, 2026·6 min read·5 visits
Absinthe versions prior to 1.10.2 are vulnerable to unauthenticated remote DoS. Attackers can submit large GraphQL SDL payloads containing unique identifiers, exhausting the BEAM atom table and crashing the host application.
CVE-2026-42793 is a critical resource exhaustion vulnerability in the Absinthe GraphQL library for Elixir. Unauthenticated attackers can exploit unsafe atom creation during Schema Definition Language (SDL) parsing to trigger a system-wide crash of the Erlang Virtual Machine (BEAM).
Absinthe is a prominent GraphQL implementation for the Elixir programming language. The library parses, validates, and executes GraphQL queries against a defined schema. During the parsing phase, Absinthe translates raw GraphQL Schema Definition Language (SDL) documents into an internal representation known as a Blueprint. This translation process is fundamental to how the library manages incoming requests and maps them to developer-defined resolvers.
CVE-2026-42793 constitutes a severe resource exhaustion flaw, categorized as CWE-770, within this parsing pipeline. The vulnerability allows an unauthenticated remote attacker to induce a complete Denial of Service (DoS) condition on the host system. This condition results in the abrupt termination of the underlying Erlang Virtual Machine (BEAM), bypassing standard error handling and recovery mechanisms.
The vulnerability specifically targets the global atom table inherent to the BEAM architecture. By supplying excessively large GraphQL documents containing unique identifiers, an attacker forces the VM to allocate unrecoverable memory constructs. Once the VM exhausts the configured atom limit, it aborts execution immediately, requiring external orchestration tools to restore service availability.
The root cause of CVE-2026-42793 resides in the improper handling of user-supplied strings during the construction of Blueprint nodes. Within the BEAM ecosystem, atoms are global constants whose names are resolved at runtime. Crucially, the BEAM architecture dictates that atoms are not subjected to garbage collection. Any atom created during the lifespan of an Erlang node persists indefinitely until the node process terminates.
To prevent unconstrained memory growth, the BEAM enforces a strict upper bound on the maximum number of atoms that can exist simultaneously. This limit defaults to 1,048,576 entries. If an application attempts to dynamically generate atoms from untrusted input via functions like String.to_atom/1, it exposes a direct vector for resource exhaustion. Once the 1,048,576th atom is generated, the VM throws a fatal system_limit error and halts entirely.
Absinthe versions between 1.5.0 and 1.10.1 utilized String.to_atom/1 to process identifiers extracted from incoming SDL documents. The SDL parser extracts string values representing directive names, field types, and argument identifiers, passing them directly to the unsafe conversion function. This architectural decision guarantees that malicious input translates directly to permanent state consumption, bypassing any application-level throttling or rate limiting.
The vulnerable implementation pattern appears across multiple SDL language modules within the Absinthe source code. Specifically, the Blueprint.Draft.convert/2 function delegates node parsing to specific type handlers. Within these handlers, the library extracts string names from the Abstract Syntax Tree (AST) and converts them directly to atoms.
The following code block demonstrates the insecure pattern located within Absinthe.Language.InterfaceTypeDefinition prior to the patch. The identifier key is populated by calling String.to_atom/1 on the user-controlled node.name parameter:
defmodule Absinthe.Language.InterfaceTypeDefinition do
def convert(node, doc) do
%Blueprint.Schema.InterfaceTypeDefinition{
name: node.name,
description: node.description,
identifier: Macro.underscore(node.name) |> String.to_atom(),
fields: Absinthe.Blueprint.Draft.convert(node.fields, doc),
directives: Absinthe.Blueprint.Draft.convert(node.directives, doc),
source_location: source_location(node)
}
end
endThe vendor addressed this issue in commit dd842b938e3823f345c10416914ffab5d5536838. Rather than replacing String.to_atom/1 with the safer String.to_existing_atom/1 in the definition models, the developers introduced a structural fix to the execution pipeline. They added the Absinthe.Phase.Document.Validation.ExecutableDefinitions phase. This phase executes immediately after the parsing phase and prior to the Blueprint conversion phase.
This new phase enforces section 5.1.1 of the GraphQL specification. It asserts that incoming documents submitted for execution contain only OperationDefinition or FragmentDefinition nodes. By rejecting TypeSystemDefinition documents early in the pipeline, the application guarantees that malicious directive or interface definitions never reach the vulnerable String.to_atom/1 calls deeper in the codebase.
Exploitation requires network access to an endpoint that accepts and parses GraphQL queries using a vulnerable version of Absinthe. The attacker does not require authentication, provided the unauthenticated user can submit queries to the GraphQL interface. The attack strategy focuses on sheer payload volume rather than complex memory corruption techniques.
An attacker constructs a payload consisting of continuous, unique TypeSystemDefinition entries. A common approach involves chaining thousands of unique directive definitions within a single HTTP request. The following GraphQL structure demonstrates the exploit methodology:
directive @exploit_000001 on FIELD
directive @exploit_000002 on FIELD
directive @exploit_000003 on FIELD
# Payload continues until the atom limit is reachedUpon receiving this document, the Absinthe parser constructs an AST and begins the conversion phase. The library invokes String.to_atom/1 for every unique directive identifier in the payload. The attacker repeats this structure until the generated identifiers exceed the BEAM's atom table limit. The following state diagram illustrates the attack execution flow:
The execution of this payload triggers an uncatchable system_limit exception within the VM. The BEAM terminates abruptly, terminating all running Erlang processes and dropping all active TCP and WebSocket connections. The target service remains unavailable until the infrastructure layer restarts the container or process.
The primary impact of CVE-2026-42793 is a total loss of system availability. Because the vulnerability targets the underlying BEAM architecture rather than an isolated worker process, the crash affects the entire Erlang node. Any background jobs, active WebSockets, or concurrent HTTP requests handled by the same VM will fail immediately upon exploitation.
This vulnerability carries a CVSS 4.0 base score of 8.2, reflecting the severe availability impact and low attack complexity. The attack requires a single HTTP request to execute, leaving minimal operational footprint in access logs prior to the crash. The lack of requisite authentication broadens the attack surface to any publicly exposed Absinthe endpoint handling internet traffic.
The blast radius extends beyond simple monolithic applications. In microservice architectures employing GraphQL Federation, a vulnerable Absinthe gateway instance can be weaponized to degrade the routing layer. An attacker targeting the gateway can cause repeated crashes, effectively severing communication to all backend subgraphs.
The standard remediation path requires upgrading the absinthe dependency to version 1.10.2. This release includes the ExecutableDefinitions validation phase, effectively mitigating the primary execution attack vector. Organizations must update their mix.exs file to require ~> 1.10.2 and run mix deps.get to secure the standard GraphQL execution pipeline.
Developers implementing custom schema parsing logic must exercise additional caution. Because the patch relies on pipeline validation rather than replacing the underlying unsafe atom creation functions, manual invocations of Absinthe.Blueprint.Draft.convert/2 remain vulnerable. Applications that dynamically ingest schemas from untrusted sources, such as schema registries, must implement custom validation layers to reject structurally anomalous SDL documents.
Organizations unable to deploy the patch immediately can deploy network-level mitigations. Web Application Firewalls (WAF) or API gateways can enforce strict payload size limits on incoming GraphQL requests. By restricting the maximum HTTP request body size, defenders can mathematically prevent attackers from transmitting the required volume of unique identifiers necessary to exhaust the default atom table limit.
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| Product | Affected Versions | Fixed Version |
|---|---|---|
absinthe absinthe-graphql | >= 1.5.0, < 1.10.2 | 1.10.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-770 |
| Attack Vector | Network |
| CVSS Score | 8.2 |
| EPSS Score | 0.00064 |
| Impact | Complete Denial of Service (VM Crash) |
| Exploit Status | Proof of Concept |
| KEV Status | Not Listed |
Allocation of Resources Without Limits or Throttling