CVE-2026-42793 Overview
CVE-2026-42793 is an unauthenticated denial-of-service vulnerability in absinthe-graphql/absinthe, the GraphQL toolkit for Elixir. The flaw resides in the Schema Definition Language (SDL) parsing path, where multiple Blueprint.Draft.convert/2 implementations invoke String.to_atom/1 on attacker-controlled identifiers. Because atoms are never garbage-collected on the BEAM virtual machine, each unique name permanently consumes a slot in the fixed-size atom table. An attacker can submit SDL documents containing enough unique directive, field, type, and argument names to exhaust the default 1,048,576-slot table and crash the Erlang node. The issue is tracked as CWE-770 and affects absinthe from 1.5.0 before 1.10.2.
Critical Impact
Any application that passes attacker-controlled GraphQL SDL to Absinthe's parser — including schema-upload endpoints, federation gateways, and developer tools — can be crashed remotely without authentication.
Affected Products
- absinthe-graphql/absinthe versions >= 1.5.0 and < 1.10.2
- Elixir applications exposing GraphQL SDL parsing to untrusted input
- GraphQL federation gateways ingesting remote SDL via Absinthe
Discovery Timeline
- 2026-05-08 - CVE-2026-42793 published to NVD
- 2026-05-13 - Last updated in NVD database
Technical Details for CVE-2026-42793
Vulnerability Analysis
Absinthe parses GraphQL SDL documents into Blueprint structures through a series of phases in its execution pipeline. During the Blueprint conversion phase, multiple Blueprint.Draft.convert/2 clauses for SDL language nodes call String.to_atom/1 on names extracted from the parsed document. These names include directive names, field names, type names, and argument names taken directly from user-supplied input.
On the BEAM virtual machine, atoms are interned in a global table that is not garbage-collected. Once an atom is created, it persists for the lifetime of the node. The default table size is 1,048,576 entries. When the table fills, the runtime aborts with a system_limit error and the entire Erlang node terminates, taking down every service running on it.
Root Cause
The root cause is unbounded resource allocation [CWE-770] triggered by use of String.to_atom/1 on untrusted input. The safer alternative String.to_existing_atom/1 would raise on unknown names, but Absinthe's SDL converters did not restrict atom creation to a known set.
Attack Vector
An unauthenticated remote attacker sends one or more SDL documents containing large numbers of unique identifiers to any endpoint that forwards SDL into Absinthe's parser. Typical exposure points include schema-upload features, federation gateways pulling subgraph SDL, and admin tooling that previews user-supplied schemas. Each unique identifier permanently consumes an atom slot; with sufficient submissions the node aborts.
The upstream fix introduces an ExecutableDefinitions validation phase that runs between parsing and Blueprint conversion, rejecting TypeSystemDefinition and TypeSystemExtension nodes in documents submitted for execution.
+defmodule Absinthe.Phase.Document.Validation.ExecutableDefinitions do
+ @moduledoc """
+ Implements GraphQL spec §5.1.1 "Executable Definitions": a document
+ submitted for execution must contain only OperationDefinition and
+ FragmentDefinition. Any TypeSystemDefinition or TypeSystemExtension
+ is invalid for execution and is rejected here.
+
+ Runs between Phase.Parse and Phase.Blueprint in the `for_document` pipeline.
+ """
+ use Absinthe.Phase
+
+ alias Absinthe.{Blueprint, Language, Phase}
+
+ @executable_definitions [Language.OperationDefinition, Language.Fragment]
+
+ @spec run(Blueprint.t(), Keyword.t()) :: Phase.result_t()
+ def run(%Blueprint{input: %Language.Document{} = document} = blueprint, options \\ []) do
+ case Enum.reject(document.definitions, &(&1.__struct__ in @executable_definitions)) do
+ [] ->
+ {:ok, blueprint}
+
+ type_definitions ->
+ errors =
+ Enum.map(type_definitions, fn node ->
+ %Phase.Error{
+ phase: __MODULE__,
+ message: "#{label(node)} is not an executable definition",
+ locations: [node.loc]
+ }
+ end)
Source: GitHub Commit dd842b9
Detection Methods for CVE-2026-42793
Indicators of Compromise
- Erlang VM crash logs containing system_limit errors referencing atom table exhaustion
- Sudden node restarts on hosts running Absinthe-based GraphQL services with no preceding deployment
- HTTP requests to GraphQL endpoints containing large SDL payloads with high cardinality of unique identifiers
Detection Strategies
- Inspect application telemetry for monotonic growth in erlang:system_info(:atom_count) over time
- Alert when atom usage exceeds a threshold percentage of erlang:system_info(:atom_limit)
- Log and review POST bodies to GraphQL endpoints that contain type, directive, or extend keywords from untrusted clients
Monitoring Recommendations
- Export BEAM atom-table metrics to your observability stack and set alerts on rapid increases
- Monitor request size and identifier cardinality on any endpoint that accepts SDL
- Correlate node restarts with upstream HTTP request volume to identify exhaustion attempts
How to Mitigate CVE-2026-42793
Immediate Actions Required
- Upgrade absinthe to version 1.10.2 or later in mix.exs and redeploy all affected services
- Audit application code paths that call Absinthe.run/3, Absinthe.Schema.Notation, or any SDL parser with user-supplied input
- Restrict or remove endpoints that allow unauthenticated users to submit SDL documents
Patch Information
The fix is included in absinthe 1.10.2. The patch adds an Absinthe.Phase.Document.Validation.ExecutableDefinitions phase to the for_document pipeline, rejecting type-system definitions and extensions before they reach Blueprint conversion. See the GitHub Security Advisory GHSA-qf4g-9fqq-mmm7 and the CNA advisory for details.
Workarounds
- Place authentication and authorization in front of any endpoint that forwards SDL to Absinthe
- Enforce strict request-size limits and reject documents containing TypeSystemDefinition nodes at the application edge
- Increase the BEAM atom limit only as a stopgap; this raises the bar but does not eliminate the underlying flaw
# Update Absinthe dependency in mix.exs, then fetch and compile
# {:absinthe, "~> 1.10.2"}
mix deps.update absinthe
mix deps.compile absinthe
mix test
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


