CVE-2026-42793
Atom table exhaustion via attacker-controlled GraphQL SDL names in absinthe
Allocation of Resources Without Limits or Throttling vulnerability in absinthe-graphql absinthe allows unauthenticated denial of service via atom table exhaustion when parsing attacker-controlled GraphQL SDL.
Multiple Blueprint.Draft.convert/2 implementations in Absinthe's SDL language modules call String.to_atom/1 on attacker-controlled names from parsed GraphQL SDL documents, including directive names, field names, type names, and argument names. Because atoms are never garbage-collected and the BEAM atom table has a fixed limit (default 1,048,576), each unique name permanently consumes one slot. An attacker can exhaust the atom table by submitting SDL documents containing enough unique names, causing the Erlang VM to abort with system_limit and taking down the entire node.
Any application that passes attacker-controlled GraphQL SDL through Absinthe's parser is exposed — for example, a schema-upload endpoint, a federation gateway that ingests remote SDL, or any developer tool that runs the parser over user-supplied documents.
This issue affects absinthe: from 1.5.0 before 1.10.2.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.2
Atom table exhaustion via attacker-controlled GraphQL SDL names in absinthe
Allocation of Resources Without Limits or Throttling vulnerability in absinthe-graphql absinthe allows unauthenticated denial of service via atom table exhaustion when parsing attacker-controlled GraphQL SDL.
Multiple Blueprint.Draft.convert/2 implementations in Absinthe's SDL language modules call String.to_atom/1 on attacker-controlled names from parsed GraphQL SDL documents, including directive names, field names, type names, and argument names. Because atoms are never garbage-collected and the BEAM atom table has a fixed limit (default 1,048,576), each unique name permanently consumes one slot. An attacker can exhaust the atom table by submitting SDL documents containing enough unique names, causing the Erlang VM to abort with system_limit and taking down the entire node.
Any application that passes attacker-controlled GraphQL SDL through Absinthe's parser is exposed — for example, a schema-upload endpoint, a federation gateway that ingests remote SDL, or any developer tool that runs the parser over user-supplied documents.
This issue affects absinthe: from 1.5.0 before 1.10.2.
- Record
CVE-2026-42793- CVSS 4.0
- 8.2 High
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 - Weakness
- CWE-770
- Updated
- 2026-11-02
EUVDEUVD-2026-28798
8.2
Allocation of Resources Without Limits or Throttling vulnerability in absinthe-graphql absinthe allows unauthenticated denial of service via atom table exhaustion when parsing attacker-controlled GraphQL SDL.
Multiple Blueprint.Draft.convert/2 implementations in Absinthe's SDL language modules call String.to_atom/1 on attacker-controlled names from parsed GraphQL SDL documents, including directive names, field names, type names, and argument names. Because atoms are never garbage-collected and the BEAM atom table has a fixed limit (default 1,048,576), each unique name permanently consumes one slot. An attacker can exhaust the atom table by submitting SDL documents containing enough unique names, causing the Erlang VM to abort with system_limit and taking down the entire node.
Any application that passes attacker-controlled GraphQL SDL through Absinthe's parser is exposed — for example, a schema-upload endpoint, a federation gateway that ingests remote SDL, or any developer tool that runs the parser over user-supplied documents.
This issue affects absinthe: from 1.5.0 before 1.10.2.
- Record
EUVD-2026-28798- CVSS 4.0
- 8.2 High
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 - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-qf4g-9fqq-mmm7
8.2
Absinthe: Unbounded atom creation from parsed directive name
Summary
When Absinthe parses a GraphQL SDL document, every directive @<name> definition is converted into a freshly created atom without any allow-list or length cap. Because atoms are never garbage-collected and the BEAM has a hard ~1,048,576 atom-table limit, any application that feeds attacker-controlled SDL through Absinthe's parser can be crashed (whole VM termination) by submitting a document containing enough unique directive names.
Introduced in https://github.com/absinthe-graphql/absinthe/commit/d0eae7764520d4e8e5dfff619068c0de911aec33
Details
In lib/absinthe/language/directive_definition.ex:27, the Blueprint.from_ast/2 conversion does:
Macro.underscore(node.name) |> String.to_atom()
node.name is taken verbatim from the parsed GraphQL document, so the atom is created before the directive has been validated against any known schema. There is no use of String.to_existing_atom/1, no length cap, and no allow-list. Each unique directive name in the input permanently consumes one slot in the global atom table.
Any code path that runs Absinthe.Phase.Parse (or any equivalent that ultimately calls Absinthe.Blueprint.Draft.convert/2 on a parsed DirectiveDefinition node) on untrusted text is exposed — for example, a schema-upload endpoint, a federation gateway that ingests remote SDL, an introspection-to-SDL converter, or any developer tool that runs the parser over user-supplied documents. An attacker only needs to submit one (or a handful of) SDL documents that together contain ~1M unique directive @<random> definitions to exhaust the atom table and crash the BEAM.
The same vulnerablity was found in these files as well:
lib/absinthe/language/enum_type_definition.ex:23lib/absinthe/language/field_definition.ex:27lib/absinthe/language/input_object_type_definition.ex:24lib/absinthe/language/input_value_definition.ex:31lib/absinthe/language/interface_type_definition.ex:26lib/absinthe/language/object_type_definition.ex:27lib/absinthe/language/scalar_type_definition.ex:23lib/absinthe/language/union_type_definition.ex:24- maybe others too.
Please do a search&replace in the whole project.
PoC
A script that parses a generated SDL document containing many unique directive @<random> definitions through Absinthe and demonstrates unbounded atom-table growth (eventually crashing the VM) is attached at the end of this report.
Impact
This is an unauthenticated denial-of-service vulnerability (atom-table exhaustion leading to BEAM VM crash) affecting any application that passes untrusted GraphQL SDL through Absinthe's parser. The crash takes down the entire Erlang node, not just the request handler, so all unrelated workloads sharing the VM are also impacted. The only precondition is that attacker-controlled text reaches the SDL parser; no authentication, schema privileges, or query execution are required.
Scripts and Logs
# Verifies: Unbounded atom creation from parsed directive name
Mix.install([
{:absinthe, "~> 1.7"},
{:absinthe_plug, "~> 1.5"},
{:bandit, "~> 1.5"},
{:plug, "~> 1.16"},
{:jason, "~> 1.4"},
{:req, "~> 0.5"}
])
# Minimal Absinthe schema -- the only thing it needs to do is exist
# so that Absinthe.Plug will parse incoming GraphQL documents.
defmodule DemoSchema do
use Absinthe.Schema
query do
field :hello, :string do
resolve fn _, _, _ -> {:ok, "world"} end
end
end
end
# Standard absinthe_plug HTTP entry point. This is the public
# trust boundary: anyone who can reach the server can POST a
# GraphQL document, which Absinthe will parse and lower into a
# Blueprint -- the path that mints atoms from directive names.
defmodule Router do
use Plug.Router
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json, Absinthe.Plug.Parser],
pass: ["*/*"],
json_decoder: Jason
plug :match
plug :dispatch
forward "/graphql", to: Absinthe.Plug, init_opts: [schema:…
- Record
GHSA-qf4g-9fqq-mmm7- CVSS 4.0
- 8.2 High
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 - Weakness
- CWE-770
- Updated
- 2026-11-02
NVD
8.2
Allocation of Resources Without Limits or Throttling vulnerability in absinthe-graphql absinthe allows unauthenticated denial of service via atom table exhaustion when parsing attacker-controlled GraphQL SDL.
Multiple Blueprint.Draft.convert/2 implementations in Absinthe's SDL language modules call String.to_atom/1 on attacker-controlled names from parsed GraphQL SDL documents, including directive names, field names, type names, and argument names. Because atoms are never garbage-collected and the BEAM atom table has a fixed limit (default 1,048,576), each unique name permanently consumes one slot. An attacker can exhaust the atom table by submitting SDL documents containing enough unique names, causing the Erlang VM to abort with system_limit and taking down the entire node.
Any application that passes attacker-controlled GraphQL SDL through Absinthe's parser is exposed — for example, a schema-upload endpoint, a federation gateway that ingests remote SDL, or any developer tool that runs the parser over user-supplied documents.
This issue affects absinthe: from 1.5.0 before 1.10.2.
- Record
CVE-2026-42793- CVSS 4.0
- 8.2 High
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-770
- Updated
- 2026-11-02
OSV
8.2
Atom table exhaustion via attacker-controlled GraphQL SDL names in absinthe
Allocation of Resources Without Limits or Throttling vulnerability in absinthe-graphql absinthe allows unauthenticated denial of service via atom table exhaustion when parsing attacker-controlled GraphQL SDL.
Multiple Blueprint.Draft.convert/2 implementations in Absinthe's SDL language modules call String.to_atom/1 on attacker-controlled names from parsed GraphQL SDL documents, including directive names, field names, type names, and argument names. Because atoms are never garbage-collected and the BEAM atom table has a fixed limit (default 1,048,576), each unique name permanently consumes one slot. An attacker can exhaust the atom table by submitting SDL documents containing enough unique names, causing the Erlang VM to abort with system_limit and taking down the entire node.
Any application that passes attacker-controlled GraphQL SDL through Absinthe's parser is exposed — for example, a schema-upload endpoint, a federation gateway that ingests remote SDL, or any developer tool that runs the parser over user-supplied documents.
This issue affects absinthe: from 1.5.0 before 1.10.2.
- Record
CVE-2026-42793- CVSS 4.0
- 8.2 High
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 - Weakness
- CWE-770
- Updated
- 2026-11-02
OSVEEF-CVE-2026-42793
8.2
Atom table exhaustion via attacker-controlled GraphQL SDL names in absinthe
Summary
Allocation of Resources Without Limits or Throttling vulnerability in absinthe-graphql absinthe allows unauthenticated denial of service via atom table exhaustion when parsing attacker-controlled GraphQL SDL.
Multiple Blueprint.Draft.convert/2 implementations in Absinthe's SDL language modules call String.to_atom/1 on attacker-controlled names from parsed GraphQL SDL documents, including directive names, field names, type names, and argument names. Because atoms are never garbage-collected and the BEAM atom table has a fixed limit (default 1,048,576), each unique name permanently consumes one slot. An attacker can exhaust the atom table by submitting SDL documents containing enough unique names, causing the Erlang VM to abort with system_limit and taking down the entire node.
Any application that passes attacker-controlled GraphQL SDL through Absinthe's parser is exposed — for example, a schema-upload endpoint, a federation gateway that ingests remote SDL, or any developer tool that runs the parser over user-supplied documents.
This issue affects absinthe: from 1.5.0 before 1.10.2.
- Record
EEF-CVE-2026-42793- CVSS 4.0
- 8.2 High
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 - Weakness
- CWE-770
- Updated
- 2026-11-02
OSVGHSA-qf4g-9fqq-mmm7
8.2
Absinthe: Unbounded atom creation from parsed directive name
Summary
When Absinthe parses a GraphQL SDL document, every directive @<name> definition is converted into a freshly created atom without any allow-list or length cap. Because atoms are never garbage-collected and the BEAM has a hard ~1,048,576 atom-table limit, any application that feeds attacker-controlled SDL through Absinthe's parser can be crashed (whole VM termination) by submitting a document containing enough unique directive names.
Introduced in https://github.com/absinthe-graphql/absinthe/commit/d0eae7764520d4e8e5dfff619068c0de911aec33
Details
In lib/absinthe/language/directive_definition.ex:27, the Blueprint.from_ast/2 conversion does:
Macro.underscore(node.name) |> String.to_atom()
node.name is taken verbatim from the parsed GraphQL document, so the atom is created before the directive has been validated against any known schema. There is no use of String.to_existing_atom/1, no length cap, and no allow-list. Each unique directive name in the input permanently consumes one slot in the global atom table.
Any code path that runs Absinthe.Phase.Parse (or any equivalent that ultimately calls Absinthe.Blueprint.Draft.convert/2 on a parsed DirectiveDefinition node) on untrusted text is exposed — for example, a schema-upload endpoint, a federation gateway that ingests remote SDL, an introspection-to-SDL converter, or any developer tool that runs the parser over user-supplied documents. An attacker only needs to submit one (or a handful of) SDL documents that together contain ~1M unique directive @<random> definitions to exhaust the atom table and crash the BEAM.
The same vulnerablity was found in these files as well:
lib/absinthe/language/enum_type_definition.ex:23lib/absinthe/language/field_definition.ex:27lib/absinthe/language/input_object_type_definition.ex:24lib/absinthe/language/input_value_definition.ex:31lib/absinthe/language/interface_type_definition.ex:26lib/absinthe/language/object_type_definition.ex:27lib/absinthe/language/scalar_type_definition.ex:23lib/absinthe/language/union_type_definition.ex:24- maybe others too.
Please do a search&replace in the whole project.
PoC
A script that parses a generated SDL document containing many unique directive @<random> definitions through Absinthe and demonstrates unbounded atom-table growth (eventually crashing the VM) is attached at the end of this report.
Impact
This is an unauthenticated denial-of-service vulnerability (atom-table exhaustion leading to BEAM VM crash) affecting any application that passes untrusted GraphQL SDL through Absinthe's parser. The crash takes down the entire Erlang node, not just the request handler, so all unrelated workloads sharing the VM are also impacted. The only precondition is that attacker-controlled text reaches the SDL parser; no authentication, schema privileges, or query execution are required.
Scripts and Logs
# Verifies: Unbounded atom creation from parsed directive name
Mix.install([
{:absinthe, "~> 1.7"},
{:absinthe_plug, "~> 1.5"},
{:bandit, "~> 1.5"},
{:plug, "~> 1.16"},
{:jason, "~> 1.4"},
{:req, "~> 0.5"}
])
# Minimal Absinthe schema -- the only thing it needs to do is exist
# so that Absinthe.Plug will parse incoming GraphQL documents.
defmodule DemoSchema do
use Absinthe.Schema
query do
field :hello, :string do
resolve fn _, _, _ -> {:ok, "world"} end
end
end
end
# Standard absinthe_plug HTTP entry point. This is the public
# trust boundary: anyone who can reach the server can POST a
# GraphQL document, which Absinthe will parse and lower into a
# Blueprint -- the path that mints atoms from directive names.
defmodule Router do
use Plug.Router
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json, Absinthe.Plug.Parser],
pass: ["*/*"],
json_decoder: Jason
plug :match
plug :dispatch
forward "/graphql", to: Absinthe.Plug, init_opts: [schema:…
- Record
GHSA-qf4g-9fqq-mmm7- CVSS 4.0
- 8.2 High
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 - Weakness
- CWE-770
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
absintheHex |
1.5.0 up to 1.10.2 | 1.10.2 |
absintheHex |
1.5.0 up to 1.10.2, plus listed versions 1.10.01.10.11.5.11.5.21.5.3 Show 28 moreShow less1.5.41.5.51.6.01.6.0-rc.01.6.0-rc.11.6.11.6.21.6.31.6.41.6.51.6.61.6.71.6.81.7.01.7.11.7.101.7.111.7.21.7.31.7.41.7.51.7.61.7.71.7.81.7.91.8.01.9.01.9.1 |
1.10.2 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-42793 is a high vulnerability (CVSS 8.2) in Absinthe-graphql Absinthe, published May 8, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.61%, the 49th percentile. Fixed in absinthe 1.10.2.
References
github.com/absinthe-graphql/absinthe/security/advisories/GHSA-qf4g-9fqq-mmm7
cna.erlef.org/cves/CVE-2026-42793.html
osv.dev/vulnerability/EEF-CVE-2026-42793
github.com/absinthe-graphql/absinthe/commit/dd842b938e3823f345c10416914ffab5d5536838
nvd.nist.gov/vuln/detail/CVE-2026-42793
github.com/advisories/GHSA-qf4g-9fqq-mmm7
Left out here: the rest of 2 source descriptions. The JSON record has them.