Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-67585

CVE-2026-67585: Absinthe Federation DoS Vulnerability

CVE-2026-67585 is a denial of service vulnerability in absinthe_federation that allows attackers to crash the Erlang VM via atom table exhaustion. This post covers technical details, affected versions, and mitigations.

Published:

CVE-2026-67585 Overview

CVE-2026-67585 is an unauthenticated denial-of-service vulnerability in the DivvyPayHQ absinthe_federation library for Elixir. The flaw resides in how the library processes the federation-mandated _entities field. Every key in the representations argument is converted to an atom via String.to_atom/1, but representations is typed as the open-ended _Any scalar, so keys bypass schema coercion. A remote attacker can submit crafted requests containing tens of thousands of unique keys per request, permanently populating the BEAM atom table until the node aborts. The issue affects absinthe_federation from version 0.1.0 before 0.9.3 and is tracked under CWE-770.

Critical Impact

An unauthenticated remote attacker can abort the Erlang VM in a small number of requests, forcing an application restart and taking the GraphQL federation service offline.

Affected Products

  • DivvyPayHQ absinthe_federation versions 0.1.0 through 0.9.2
  • Elixir applications running the Absinthe GraphQL federation library on the BEAM virtual machine
  • Any GraphQL supergraph exposing the federation _entities resolver to untrusted clients

Discovery Timeline

  • 2026-08-07 - CVE-2026-67585 published to NVD
  • 2026-08-12 - Last updated in NVD database

Technical Details for CVE-2026-67585

Vulnerability Analysis

The vulnerability is an allocation-of-resources-without-limits flaw [CWE-770] in the Apollo Federation implementation for the Absinthe GraphQL toolkit. Federation clients call the _entities field to resolve entity references across a supergraph. Each reference is a JSON object typed as the _Any scalar, which by specification accepts arbitrary shape.

The function convert_key/2 in lib/absinthe/federation/schema/entities_field.ex recursively walks every representation object and calls String.to_atom/1 on every key. Atoms in the BEAM are stored in a global, never-garbage-collected table capped at approximately 1,048,576 entries by default. An attacker who submits a request with unique, attacker-chosen keys creates one permanent atom per key. A handful of such requests exhausts the atom table, and the runtime aborts the node.

The impact is scoped to availability. No data confidentiality or integrity is affected, and recovery requires restarting the application process.

Root Cause

The root cause is trusting client-supplied string keys as safe input for String.to_atom/1. Because representations is typed as _Any, the schema does not constrain key names, allowing arbitrary strings to reach the atom conversion path. The safe alternative, String.to_existing_atom/1, was not used, so atom creation was unbounded.

Attack Vector

Exploitation requires only network access to the GraphQL endpoint exposing the federation _entities resolver. No authentication and no user interaction are needed. An attacker sends a GraphQL query invoking _entities with a representations array containing objects whose keys are randomly generated strings, repeating across a small number of requests until the atom table is saturated.

elixir
# Security patch in lib/absinthe/federation/schema/entities_field.ex
# Fix atom exhaustion denial of service in `_entities` (#133)

-  defp convert_keys_to_atom(map, context) when is_map(map) do
+  # Representation keys come from the open-ended `_Any` scalar, i.e. arbitrary
+  # client-supplied strings that bypass schema coercion. We only use atoms that
+  # already exist since every field of every type in the schema is an atom at
+  # compile time, so legitimate keys always convert.
+  # Unknown keys stay strings instead of being dropped.
+  defp convert_keys_to_atom(map, context) when is_map(map) and not is_struct(map) do
     Map.new(map, fn {k, v} ->
-      k = convert_key(k, context)
-      v = convert_keys_to_atom(v, context)
-      {k, v}
+      {convert_key(k, context), convert_keys_to_atom(v, context)}
     end)
   end

   defp convert_keys_to_atom(v, _context), do: v

-  defp convert_key(k, context) do
-    adapter = Map.get(context, :adapter, LanguageConventions)
+  defp convert_key(k, context) when is_binary(k) do
+    adapter = Map.get(context, :adapter) || LanguageConventions

Source: GitHub Commit c3838cd

The fix restricts atom conversion to keys that already exist in the schema, so attacker-controlled strings no longer create new atoms.

Detection Methods for CVE-2026-67585

Indicators of Compromise

  • GraphQL POST requests targeting the _entities field with unusually large representations arrays containing high-entropy or random-looking key names.
  • BEAM runtime crash logs referencing system_limit errors, atom table exhaustion, or no more index entries in atom_tab.
  • Sudden application restarts of Elixir services running Absinthe federation shortly after receipt of external GraphQL traffic.

Detection Strategies

  • Instrument the GraphQL layer to record the number of unique keys per _Any representation and alert when the count exceeds a normal-operations threshold.
  • Monitor the BEAM :erlang.system_info(:atom_count) gauge and alert on rapid growth rates that diverge from steady-state baselines.
  • Inspect web application firewall or reverse proxy logs for repeated GraphQL queries containing the _entities selector paired with large JSON payloads from a single source.

Monitoring Recommendations

  • Ship BEAM VM metrics, including atom count and process count, into a centralized observability pipeline for trend analysis.
  • Correlate GraphQL request telemetry with Erlang node restarts to identify request patterns that precede crashes.
  • Add rate-limiting and body-size limits at the ingress tier for GraphQL endpoints exposing federation resolvers.

How to Mitigate CVE-2026-67585

Immediate Actions Required

  • Upgrade absinthe_federation to version 0.9.3 or later in every deployed Elixir service.
  • Audit dependency manifests (mix.exs and mix.lock) across all repositories to confirm no service pins a vulnerable release.
  • Restart affected nodes after upgrade to clear any partially populated atom tables from prior exposure.

Patch Information

The fix is delivered in absinthe_federation0.9.3 via commit c3838cda2a7f65c4893291668c223b0d6acf4516. The patch changes convert_key/2 to resolve only atoms that already exist in the schema and leaves unknown keys as strings. See the GitHub Security Advisory GHSA-55hv-mwvr-phf3, the CNA advisory from the Erlang Ecosystem Foundation, and the OSV vulnerability record.

Workarounds

  • Front the GraphQL endpoint with a proxy that rejects requests whose JSON body exceeds a conservative size and key-count budget.
  • Enforce authentication or mutual TLS on the federation gateway so unauthenticated clients cannot invoke _entities directly.
  • Increase the BEAM atom table limit with the +t runtime flag as a short-term buffer only; this does not eliminate the vulnerability.
bash
# Update the dependency in mix.exs to the patched release
# {:absinthe_federation, "~> 0.9.3"}

mix deps.update absinthe_federation
mix deps.get
mix compile

# Verify the resolved version
mix deps | grep absinthe_federation

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.