CVE-2026-54894 (GCVE-0-2026-54894)

Vulnerability from cvelistv5 – Published: 2026-08-01 18:46 – Updated: 2026-08-01 18:46
VLAI
Title
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
Summary
Allocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-influenced binary input. Guardian.Plug.Keys derives connection and session namespace keys by passing arbitrary binaries to String.to_atom/1. base_key/1 in lib/guardian/plug/keys.ex converts any binary into the atom :"guardian_<input>", and the derived helpers claims_key/1, resource_key/1, and token_key/1 create a second atom on top of that. key_from_other/1 likewise converts a regex-captured binary through String.to_atom/1. The public specs advertise String.t() as a valid argument, so passing a string is documented usage, and higher-level entry points such as Guardian.Plug.current_token(conn, key: key) thread the caller-supplied key straight into these functions. String.to_atom/1 creates a brand-new atom for every previously unseen binary, atoms are never garbage collected, and the BEAM atom table is fixed at roughly 1,048,576 entries by default. An application that routes attacker-influenced data (a tenant identifier, header, or other request input) into a Guardian key therefore mints one permanent atom per distinct value. A modest stream of varied, unauthenticated input permanently consumes the atom table and crashes the BEAM node, taking down every application running on it. This issue affects guardian: from 0.1.0 before 2.4.1.
CWE
  • CWE-770 - Allocation of Resources Without Limits or Throttling
Assigner
EEF
Impacted products
Vendor Product Version
ueberauth guardian Affected: 0.1.0 , < 2.4.1 (semver)
    cpe:2.3:a:ueberauth:guardian:*:*:*:*:*:*:*:*
Create a notification for this product.
ueberauth guardian Affected: 7126fa433afc2563fcac0c9aa35193965f8fd5f8 , < 2952657e42e6341a67e6aaad09d8f0b40ae917cb (git)
    cpe:2.3:a:ueberauth:guardian:*:*:*:*:*:*:*:*
Create a notification for this product.
Credits
Peter Ullrich Yordis Prieto Jonatan Männchen / EEF
Show details on NVD website

{
  "containers": {
    "cna": {
      "affected": [
        {
          "collectionURL": "https://repo.hex.pm",
          "cpes": [
            "cpe:2.3:a:ueberauth:guardian:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Guardian.Plug.Keys\u0027"
          ],
          "packageName": "guardian",
          "packageURL": "pkg:hex/guardian",
          "product": "guardian",
          "programFiles": [
            "lib/guardian/plug/keys.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Guardian.Plug.Keys\u0027:base_key/1"
            },
            {
              "name": "\u0027Elixir.Guardian.Plug.Keys\u0027:claims_key/1"
            },
            {
              "name": "\u0027Elixir.Guardian.Plug.Keys\u0027:resource_key/1"
            },
            {
              "name": "\u0027Elixir.Guardian.Plug.Keys\u0027:token_key/1"
            },
            {
              "name": "\u0027Elixir.Guardian.Plug.Keys\u0027:key_from_other/1"
            }
          ],
          "repo": "https://github.com/ueberauth/guardian",
          "vendor": "ueberauth",
          "versions": [
            {
              "lessThan": "2.4.1",
              "status": "affected",
              "version": "0.1.0",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:ueberauth:guardian:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "\u0027Elixir.Guardian.Plug.Keys\u0027"
          ],
          "packageName": "ueberauth/guardian",
          "packageURL": "pkg:github/ueberauth/guardian",
          "product": "guardian",
          "programFiles": [
            "lib/guardian/plug/keys.ex"
          ],
          "programRoutines": [
            {
              "name": "\u0027Elixir.Guardian.Plug.Keys\u0027:base_key/1"
            },
            {
              "name": "\u0027Elixir.Guardian.Plug.Keys\u0027:claims_key/1"
            },
            {
              "name": "\u0027Elixir.Guardian.Plug.Keys\u0027:resource_key/1"
            },
            {
              "name": "\u0027Elixir.Guardian.Plug.Keys\u0027:token_key/1"
            },
            {
              "name": "\u0027Elixir.Guardian.Plug.Keys\u0027:key_from_other/1"
            }
          ],
          "repo": "https://github.com/ueberauth/guardian",
          "vendor": "ueberauth",
          "versions": [
            {
              "lessThan": "2952657e42e6341a67e6aaad09d8f0b40ae917cb",
              "status": "affected",
              "version": "7126fa433afc2563fcac0c9aa35193965f8fd5f8",
              "versionType": "git"
            }
          ]
        }
      ],
      "configurations": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eOnly applications that derive a Guardian key (the conn/session namespace) from attacker-influenced data are exploitable. This is the case when a caller-supplied value such as a tenant identifier, request header, or other request input is passed as the \u003ctt\u003e:key\u003c/tt\u003e option to entry points like \u003ctt\u003eGuardian.Plug.current_token/2\u003c/tt\u003e. Applications that use a static namespace (the default \u003ctt\u003e:default\u003c/tt\u003e key or hardcoded atoms) are not affected.\u003c/p\u003e"
            }
          ],
          "value": "Only applications that derive a Guardian key (the conn/session namespace) from attacker-influenced data are exploitable. This is the case when a caller-supplied value such as a tenant identifier, request header, or other request input is passed as the :key option to entry points like Guardian.Plug.current_token/2. Applications that use a static namespace (the default :default key or hardcoded atoms) are not affected."
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:ueberauth:guardian:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "2.4.1",
                  "versionStartIncluding": "0.1.0",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "AND"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Peter Ullrich"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Yordis Prieto"
        },
        {
          "lang": "en",
          "type": "analyst",
          "value": "Jonatan M\u00e4nnchen / EEF"
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-influenced binary input.\u003c/p\u003e\u003cp\u003e\u003ctt\u003eGuardian.Plug.Keys\u003c/tt\u003e derives connection and session namespace keys by passing arbitrary binaries to \u003ctt\u003eString.to_atom/1\u003c/tt\u003e. \u003ctt\u003ebase_key/1\u003c/tt\u003e in \u003ctt\u003elib/guardian/plug/keys.ex\u003c/tt\u003e converts any binary into the atom \u003ctt\u003e:\"guardian_\u0026lt;input\u0026gt;\"\u003c/tt\u003e, and the derived helpers \u003ctt\u003eclaims_key/1\u003c/tt\u003e, \u003ctt\u003eresource_key/1\u003c/tt\u003e, and \u003ctt\u003etoken_key/1\u003c/tt\u003e create a second atom on top of that. \u003ctt\u003ekey_from_other/1\u003c/tt\u003e likewise converts a regex-captured binary through \u003ctt\u003eString.to_atom/1\u003c/tt\u003e. The public specs advertise \u003ctt\u003eString.t()\u003c/tt\u003e as a valid argument, so passing a string is documented usage, and higher-level entry points such as \u003ctt\u003eGuardian.Plug.current_token(conn, key: key)\u003c/tt\u003e thread the caller-supplied key straight into these functions.\u003c/p\u003e\u003cp\u003e\u003ctt\u003eString.to_atom/1\u003c/tt\u003e creates a brand-new atom for every previously unseen binary, atoms are never garbage collected, and the BEAM atom table is fixed at roughly 1,048,576 entries by default. An application that routes attacker-influenced data (a tenant identifier, header, or other request input) into a Guardian key therefore mints one permanent atom per distinct value. A modest stream of varied, unauthenticated input permanently consumes the atom table and crashes the BEAM node, taking down every application running on it.\u003c/p\u003e\u003cp\u003eThis issue affects guardian: from 0.1.0 before 2.4.1.\u003c/p\u003e"
            }
          ],
          "value": "Allocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-influenced binary input.\n\nGuardian.Plug.Keys derives connection and session namespace keys by passing arbitrary binaries to String.to_atom/1. base_key/1 in lib/guardian/plug/keys.ex converts any binary into the atom :\"guardian_\u003cinput\u003e\", and the derived helpers claims_key/1, resource_key/1, and token_key/1 create a second atom on top of that. key_from_other/1 likewise converts a regex-captured binary through String.to_atom/1. The public specs advertise String.t() as a valid argument, so passing a string is documented usage, and higher-level entry points such as Guardian.Plug.current_token(conn, key: key) thread the caller-supplied key straight into these functions.\n\nString.to_atom/1 creates a brand-new atom for every previously unseen binary, atoms are never garbage collected, and the BEAM atom table is fixed at roughly 1,048,576 entries by default. An application that routes attacker-influenced data (a tenant identifier, header, or other request input) into a Guardian key therefore mints one permanent atom per distinct value. A modest stream of varied, unauthenticated input permanently consumes the atom table and crashes the BEAM node, taking down every application running on it.\n\nThis issue affects guardian: from 0.1.0 before 2.4.1."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-130",
          "descriptions": [
            {
              "lang": "en",
              "value": "CAPEC-130 Excessive Allocation"
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "attackComplexity": "LOW",
            "attackRequirements": "PRESENT",
            "attackVector": "LOCAL",
            "baseScore": 6.9,
            "baseSeverity": "MEDIUM",
            "privilegesRequired": "NONE",
            "subAvailabilityImpact": "HIGH",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "vectorString": "CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:H",
            "version": "4.0",
            "vulnAvailabilityImpact": "HIGH",
            "vulnConfidentialityImpact": "NONE",
            "vulnIntegrityImpact": "NONE"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-770",
              "description": "CWE-770 Allocation of Resources Without Limits or Throttling",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-08-01T18:46:05.861Z",
        "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "shortName": "EEF"
      },
      "references": [
        {
          "tags": [
            "vendor-advisory",
            "related"
          ],
          "url": "https://github.com/ueberauth/guardian/security/advisories/GHSA-xqch-c77q-rgh5"
        },
        {
          "tags": [
            "related"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-54894.html"
        },
        {
          "tags": [
            "related"
          ],
          "url": "https://osv.dev/vulnerability/EEF-CVE-2026-54894"
        },
        {
          "tags": [
            "patch"
          ],
          "url": "https://github.com/ueberauth/guardian/commit/2952657e42e6341a67e6aaad09d8f0b40ae917cb"
        }
      ],
      "source": {
        "discovery": "EXTERNAL"
      },
      "title": "Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys",
      "workarounds": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eDo not derive Guardian keys from untrusted input. Use a fixed, hardcoded set of namespace keys, or validate the value against a bounded allowlist of known keys, before passing it as the \u003ctt\u003e:key\u003c/tt\u003e option.\u003c/p\u003e"
            }
          ],
          "value": "Do not derive Guardian keys from untrusted input. Use a fixed, hardcoded set of namespace keys, or validate the value against a bounded allowlist of known keys, before passing it as the :key option."
        }
      ],
      "x_generator": {
        "engine": "cvelib 1.8.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
    "assignerShortName": "EEF",
    "cveId": "CVE-2026-54894",
    "datePublished": "2026-08-01T18:46:05.861Z",
    "dateReserved": "2026-06-16T10:47:13.915Z",
    "dateUpdated": "2026-08-01T18:46:05.861Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "vulnerability-lookup:meta": {
    "epss": {
      "cve": "CVE-2026-54894",
      "date": "2026-08-03",
      "epss": "0.00126",
      "percentile": "0.02707"
    },
    "nvd": "{\"cve\":{\"id\":\"CVE-2026-54894\",\"sourceIdentifier\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\",\"published\":\"2026-08-01T19:16:41.977\",\"lastModified\":\"2026-08-01T19:16:41.977\",\"vulnStatus\":\"Received\",\"cveTags\":[],\"descriptions\":[{\"lang\":\"en\",\"value\":\"Allocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-influenced binary input.\\n\\nGuardian.Plug.Keys derives connection and session namespace keys by passing arbitrary binaries to String.to_atom/1. base_key/1 in lib/guardian/plug/keys.ex converts any binary into the atom :\\\"guardian_\u003cinput\u003e\\\", and the derived helpers claims_key/1, resource_key/1, and token_key/1 create a second atom on top of that. key_from_other/1 likewise converts a regex-captured binary through String.to_atom/1. The public specs advertise String.t() as a valid argument, so passing a string is documented usage, and higher-level entry points such as Guardian.Plug.current_token(conn, key: key) thread the caller-supplied key straight into these functions.\\n\\nString.to_atom/1 creates a brand-new atom for every previously unseen binary, atoms are never garbage collected, and the BEAM atom table is fixed at roughly 1,048,576 entries by default. An application that routes attacker-influenced data (a tenant identifier, header, or other request input) into a Guardian key therefore mints one permanent atom per distinct value. A modest stream of varied, unauthenticated input permanently consumes the atom table and crashes the BEAM node, taking down every application running on it.\\n\\nThis issue affects guardian: from 0.1.0 before 2.4.1.\"}],\"affected\":[{\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\",\"affectedData\":[{\"vendor\":\"ueberauth\",\"product\":\"guardian\",\"defaultStatus\":\"unaffected\",\"collectionURL\":\"https://repo.hex.pm\",\"packageName\":\"guardian\",\"cpes\":[\"cpe:2.3:a:ueberauth:guardian:*:*:*:*:*:*:*:*\"],\"modules\":[\"\u0027Elixir.Guardian.Plug.Keys\u0027\"],\"programFiles\":[\"lib/guardian/plug/keys.ex\"],\"programRoutines\":[{\"name\":\"\u0027Elixir.Guardian.Plug.Keys\u0027:base_key/1\"},{\"name\":\"\u0027Elixir.Guardian.Plug.Keys\u0027:claims_key/1\"},{\"name\":\"\u0027Elixir.Guardian.Plug.Keys\u0027:resource_key/1\"},{\"name\":\"\u0027Elixir.Guardian.Plug.Keys\u0027:token_key/1\"},{\"name\":\"\u0027Elixir.Guardian.Plug.Keys\u0027:key_from_other/1\"}],\"repo\":\"https://github.com/ueberauth/guardian\",\"packageURL\":\"pkg:hex/guardian\",\"versions\":[{\"version\":\"0.1.0\",\"lessThan\":\"2.4.1\",\"versionType\":\"semver\",\"status\":\"affected\"}]},{\"vendor\":\"ueberauth\",\"product\":\"guardian\",\"defaultStatus\":\"unaffected\",\"collectionURL\":\"https://github.com\",\"packageName\":\"ueberauth/guardian\",\"cpes\":[\"cpe:2.3:a:ueberauth:guardian:*:*:*:*:*:*:*:*\"],\"modules\":[\"\u0027Elixir.Guardian.Plug.Keys\u0027\"],\"programFiles\":[\"lib/guardian/plug/keys.ex\"],\"programRoutines\":[{\"name\":\"\u0027Elixir.Guardian.Plug.Keys\u0027:base_key/1\"},{\"name\":\"\u0027Elixir.Guardian.Plug.Keys\u0027:claims_key/1\"},{\"name\":\"\u0027Elixir.Guardian.Plug.Keys\u0027:resource_key/1\"},{\"name\":\"\u0027Elixir.Guardian.Plug.Keys\u0027:token_key/1\"},{\"name\":\"\u0027Elixir.Guardian.Plug.Keys\u0027:key_from_other/1\"}],\"repo\":\"https://github.com/ueberauth/guardian\",\"packageURL\":\"pkg:github/ueberauth/guardian\",\"versions\":[{\"version\":\"7126fa433afc2563fcac0c9aa35193965f8fd5f8\",\"lessThan\":\"2952657e42e6341a67e6aaad09d8f0b40ae917cb\",\"versionType\":\"git\",\"status\":\"affected\"}]}]}],\"metrics\":{\"cvssMetricV40\":[{\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\",\"type\":\"Secondary\",\"cvssData\":{\"version\":\"4.0\",\"vectorString\":\"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:H/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\",\"baseScore\":6.9,\"baseSeverity\":\"MEDIUM\",\"attackVector\":\"LOCAL\",\"attackComplexity\":\"LOW\",\"attackRequirements\":\"PRESENT\",\"privilegesRequired\":\"NONE\",\"userInteraction\":\"NONE\",\"vulnConfidentialityImpact\":\"NONE\",\"vulnIntegrityImpact\":\"NONE\",\"vulnAvailabilityImpact\":\"HIGH\",\"subConfidentialityImpact\":\"NONE\",\"subIntegrityImpact\":\"NONE\",\"subAvailabilityImpact\":\"HIGH\",\"exploitMaturity\":\"NOT_DEFINED\",\"confidentialityRequirement\":\"NOT_DEFINED\",\"integrityRequirement\":\"NOT_DEFINED\",\"availabilityRequirement\":\"NOT_DEFINED\",\"modifiedAttackVector\":\"NOT_DEFINED\",\"modifiedAttackComplexity\":\"NOT_DEFINED\",\"modifiedAttackRequirements\":\"NOT_DEFINED\",\"modifiedPrivilegesRequired\":\"NOT_DEFINED\",\"modifiedUserInteraction\":\"NOT_DEFINED\",\"modifiedVulnConfidentialityImpact\":\"NOT_DEFINED\",\"modifiedVulnIntegrityImpact\":\"NOT_DEFINED\",\"modifiedVulnAvailabilityImpact\":\"NOT_DEFINED\",\"modifiedSubConfidentialityImpact\":\"NOT_DEFINED\",\"modifiedSubIntegrityImpact\":\"NOT_DEFINED\",\"modifiedSubAvailabilityImpact\":\"NOT_DEFINED\",\"Safety\":\"NOT_DEFINED\",\"Automatable\":\"NOT_DEFINED\",\"Recovery\":\"NOT_DEFINED\",\"valueDensity\":\"NOT_DEFINED\",\"vulnerabilityResponseEffort\":\"NOT_DEFINED\",\"providerUrgency\":\"NOT_DEFINED\"}}]},\"weaknesses\":[{\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\",\"type\":\"Secondary\",\"description\":[{\"lang\":\"en\",\"value\":\"CWE-770\"}]}],\"references\":[{\"url\":\"https://cna.erlef.org/cves/CVE-2026-54894.html\",\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\"},{\"url\":\"https://github.com/ueberauth/guardian/commit/2952657e42e6341a67e6aaad09d8f0b40ae917cb\",\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\"},{\"url\":\"https://github.com/ueberauth/guardian/security/advisories/GHSA-xqch-c77q-rgh5\",\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\"},{\"url\":\"https://osv.dev/vulnerability/EEF-CVE-2026-54894\",\"source\":\"6b3ad84c-e1a6-4bf7-a703-f496b71e49db\"}]}}"
  }
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Loading…