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

CVE-2026-55733: Ueberauth Guardian DOS Vulnerability

CVE-2026-55733 is a denial of service flaw in Ueberauth Guardian caused by unbounded atom creation from untrusted input. Attackers can exhaust the BEAM atom table and crash the system. This article covers technical details, affected versions, impact, and mitigation strategies.

Published:

CVE-2026-55733 Overview

CVE-2026-55733 is a denial-of-service vulnerability in the ueberauth guardian authentication library for Elixir. The flaw affects the Guardian.Permissions.AtomEncoding module, which passes attacker-controlled binary input directly to String.to_atom/1 without an allow-list check. Because the Erlang BEAM virtual machine never garbage collects atoms and caps the atom table at roughly 1,048,576 entries by default, a stream of unique permission strings can exhaust the table and crash the node with system_limit. The issue affects Guardian versions 2.0.0 through 2.4.0 and is categorized under [CWE-770] Allocation of Resources Without Limits or Throttling.

Critical Impact

Attacker-influenced permission scopes routed through encode/3 mint one permanent atom per distinct value, permanently consuming the BEAM atom table and taking down every application running on the node.

Affected Products

  • ueberauth guardian versions 2.0.0 through 2.4.0
  • Elixir applications using Guardian.Permissions with encoding: Guardian.Permissions.AtomEncoding
  • BEAM nodes running affected Guardian versions with attacker-influenced permission input

Discovery Timeline

  • 2026-08-01 - CVE-2026-55733 published to NVD
  • 2026-08-06 - Last updated in NVD database

Technical Details for CVE-2026-55733

Vulnerability Analysis

The vulnerability resides in lib/guardian/permissions/atom_encoding.ex. When encode/3 receives a list of permission values, each binary entry is dispatched to the encode_value/3 binary clause. That clause calls String.to_atom(value) without validating the value against the application's finite perm_set. The perm_set argument, which represents the legitimate set of permission names, is discarded during binary handling.

External strings flow directly into atom creation. Attackers can supply values through a request body, a JSON Web Token (JWT) claim, or any other input path that reaches encode/3. Each previously unseen binary produces a new atom.

The default encoder Guardian.Permissions.BitwiseEncoding is not affected. Only applications explicitly configured with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding are exposed.

Root Cause

The root cause is the absence of an allow-list check in the binary clause of encode_value/3. String.to_atom/1 creates a permanent atom for any binary passed to it. Atoms in the BEAM are never garbage collected, and the atom table has a fixed default limit of approximately 1,048,576 entries. Discarding perm_set while accepting arbitrary binaries turns permission encoding into an unbounded resource allocation primitive.

Attack Vector

An unauthenticated attacker sends a modest stream of requests containing varied permission scope strings. Each unique string permanently occupies one slot in the atom table. Once the table is exhausted, the BEAM node crashes with a system_limit error, terminating every application hosted on that node.

elixir
// Patch to lib/guardian/permissions/atom_encoding.ex
   defp encode_value(value, _perm_set, acc) when is_atom(value),
     do: [value | acc]
 
-  defp encode_value(value, _perm_set, acc) when is_binary(value),
-    do: [String.to_atom(value) | acc]
+  defp encode_value(value, perm_set, acc) when is_binary(value) do
+    if is_map(perm_set) and Map.has_key?(perm_set, value) do
+      [String.to_existing_atom(value) | acc]
+    else
+      acc
+    end
+  end
 
   def decode(value, _type, _perm_set) do
     value

Source: ueberauth/guardian commit 9cd2685. The patch validates each binary against perm_set and uses String.to_existing_atom/1, which raises rather than creating new atoms.

Detection Methods for CVE-2026-55733

Indicators of Compromise

  • Steady growth in :erlang.system_info(:atom_count) approaching the :atom_limit value
  • BEAM node crashes with system_limit errors referencing atom table exhaustion
  • High volume of authentication or permission-check requests containing varied, non-standard scope strings
  • Application logs showing repeated calls into Guardian.Permissions.AtomEncoding.encode/3

Detection Strategies

  • Instrument the BEAM with periodic sampling of :erlang.memory(:atom) and :erlang.system_info(:atom_count) and alert on sustained upward trends
  • Inspect HTTP requests and JWT payloads for permission scope values that fall outside the application's declared perm_set
  • Audit application configuration for use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding to identify exposed services

Monitoring Recommendations

  • Forward BEAM VM telemetry (atom count, memory, scheduler utilization) to a centralized logging or observability platform
  • Configure alerts when atom count exceeds a defined threshold, such as 75% of :atom_limit
  • Correlate authentication endpoint traffic volume with atom growth to identify probing activity

How to Mitigate CVE-2026-55733

Immediate Actions Required

  • Upgrade ueberauth guardian to version 2.4.1 or later, which enforces perm_set validation and uses String.to_existing_atom/1
  • Audit application code for the Guardian.Permissions.AtomEncoding encoder and switch to the default Guardian.Permissions.BitwiseEncoding if atom encoding is not required
  • Validate and reject unknown permission scope values at the application boundary before they reach encode/3

Patch Information

The fix is delivered in Guardian 2.4.1 via commit 9cd2685. Details are available in the GitHub Security Advisory GHSA-fjr5-7xrc-hmpj and the Erlang Ecosystem Foundation CNA advisory.

Workarounds

  • Switch the encoder configuration from Guardian.Permissions.AtomEncoding to the default Guardian.Permissions.BitwiseEncoding, which is not affected
  • Add strict input validation ahead of Guardian to reject any permission string not present in the application's declared permission set
  • Increase the BEAM atom limit with the +t runtime flag as a temporary buffer while planning the upgrade, noting that this only delays exhaustion
bash
# Update mix.exs dependency to the patched version
# {:guardian, "~> 2.4.1"}
mix deps.update guardian
mix deps.get

# Optional: raise the atom table ceiling as a temporary buffer
# elixir --erl "+t 5242880" -S mix phx.server

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.