guardian
Elixir Authentication framework
Activity
- Latest release
- 3w ago
- Total releases
- 55
- Cadence
- ~33 days
- Last 12 months
- 2
Reach
- Downloads
- 16.1M
Details
- License
- MIT
- First release
- Jun 19, 2015
| Version | Released | |
|---|---|---|
2.5.0
minor
| ||
2.4.1
patch
| ||
2.4.0
minor
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.3.2
patch
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.3.1
patch
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.3.0
minor
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.2.4
patch
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.2.3
patch
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.2.2
patch
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.2.1
patch
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.2.0
minor
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.1.2
patch
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.1.1
minor
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
2.0.0
major
4 CVEs
CVE-2026-55734
EEF-CVE-2026-55734
GHSA-9qx2-v587-q3gg
Aug 01, 2026
guardian atom exhaustion in Guardian.Permissions.encode_permissions!/1
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling vulnerability in ueberauth guardian (Guardian.Permissions module) allows a denial of service via BEAM atom-table exhaustion. This vulnerability is associated with program file lib/guardian/permissions.ex and program routines 'Elixir.Guardian.Permissions':encode_permissions!/1, 'Elixir.Guardian.Permissions':encode_permissions_into_claims!/2, 'Elixir.Guardian.Permissions':do_encode_permissions!/2. The Guardian.Permissions mixin installs a public encode_permissions!/1 function on every module that does use Guardian.Permissions. For each key of the supplied map, encode_permissions!/1 calls String.to_atom(to_string(k)) before any validation runs. The integer-value clause of do_encode_permissions!/2 then short-circuits straight to encoding without validating the key against the configured permission set, so a key with an integer value is interned as a fresh atom with no exception raised. Atoms are never garbage collected and the BEAM atom table is a fixed-size resource (default roughly 1,048,576 entries), so each unique attacker-chosen key permanently consumes one slot. An attacker who can influence a permission map that reaches encode_permissions!/1 (for example a permissions map read from a request body and passed into token issuance via encode_permissions_into_claims!/2) can mint an unbounded number of atoms and exhaust the atom table, crashing the entire BEAM node and every service running on it. The sibling decode_permissions/1 is not affected because it skips keys absent from the configured permission set. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsBefore calling encode_permissions!/1 or encode_permissions_into_claims!/2, filter the permission map so that only keys belonging to the configured permission set are passed in, discarding any unknown keys. Avoid passing attacker-influenced permission maps into these functions. ConfigurationsThis vulnerability is only exploitable in applications that use Guardian.Permissions (via use Guardian.Permissions) and route attacker-influenced data into encode_permissions!/1 or encode_permissions_into_claims!/2, for example by reading a permissions map from a request body and passing it into token issuance. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55733
EEF-CVE-2026-55733
GHSA-fjr5-7xrc-hmpj
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian permissions AtomEncoding via unbounded atom creation
High
Local
Low
None
None
SummaryAllocation of Resources Without Limits or Throttling in ueberauth guardian allows denial of service via unbounded atom creation from attacker-controlled binary input. Guardian.Permissions.AtomEncoding encodes permission scopes by passing arbitrary binaries to String.to_atom/1. When encode/3 in lib/guardian/permissions/atom_encoding.ex is called with a list, each binary entry is handled by the encode_value/3 binary clause, which calls String.to_atom(value) with no allow-list check. The perm_set argument (the application's small, finite set of legitimate permission names) is discarded, so any external string flows straight into atom creation. This encoder is selected with use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding and reached through the imported encode/3 entry point. 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 funnels attacker-influenced permission scopes (from a request body, a JWT claim, or other external input) into encode/3 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 with system_limit, taking down every application running on it. The default encoder is Guardian.Permissions.BitwiseEncoding, which is not affected. This issue affects guardian: from 2.0.0 before 2.4.1. WorkaroundsSwitch the permission encoder to the default Guardian.Permissions.BitwiseEncoding or to Guardian.Permissions.TextEncoding, neither of which creates atoms. Alternatively, validate every permission value against the configured perm_set allowlist (rejecting unknown values) before passing it to encode/3. ConfigurationsOnly applications that opt into the non-default Guardian.Permissions.AtomEncoding encoder (via use Guardian.Permissions, encoding: Guardian.Permissions.AtomEncoding) and pass attacker-influenced permission scopes into its encode/3 entry point are exploitable. The default Guardian.Permissions.BitwiseEncoding encoder and the Guardian.Permissions.TextEncoding encoder do not create atoms and are not affected. Affected versions
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
1.2.1
patch
2 CVEs
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
1.2.0
minor
2 CVEs
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.14.6
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
1.1.1
patch
2 CVEs
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
1.1.0
minor
2 CVEs
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
1.0.1
patch
2 CVEs
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
1.0.0
major
2 CVEs
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev
CVE-2026-55735
EEF-CVE-2026-55735
GHSA-7975-hp3r-5qhv
Aug 01, 2026
Guardian.revoke/3 acts on unverified token claims, allowing forged-token session revocation
High
Network
Low
None
None
SummaryImproper Verification of Cryptographic Signature in ueberauth guardian allows an unauthenticated attacker to revoke a victim's session with a forged token. Guardian.revoke/3 in lib/guardian.ex decodes the supplied token with peek/1, which performs no signature verification (it only base64-decodes the JWT header and payload). The resulting unverified claims are forwarded directly to the configured token module's revoke callback and the implementation's on_revoke callback, a state-mutating sink. The sibling operations refresh/2 and exchange/4 both call decode_and_verify first, so the signature is checked before anything acts on the claims; revoke/3 is the only state-mutating path that acts on claims without verifying the signature. An attacker who knows or guesses a victim's identifying claim values (jti, sub) can forge a JWT carrying those claims, sign it with an arbitrary key, and submit it to any endpoint that funnels a caller-supplied token into Guardian.revoke/3 (the standard logout / session-revocation pattern). When the token module mutates state keyed by the claims (whitelist deletion or blacklist insertion, for example a GuardianDb-style store), the victim's legitimate session is evicted. This is an unauthenticated session-revocation denial of service; the attacker never needs the signing secret. This issue affects guardian: from 1.0.0 before 2.4.1. WorkaroundsVerify the token before revoking it: call decode_and_verify (or a verify-without-expiry variant, so already-expired tokens remain revocable) on the caller-supplied token and pass only tokens whose signature validates into Guardian.revoke/3. Reject tokens with an invalid signature at the application boundary. ConfigurationsThe application must route a caller-supplied token into Guardian.revoke/3 (for example a logout or session-revocation endpoint) and use a token module whose revoke / on_revoke callback mutates state keyed by the token claims (a whitelist that deletes by jti or a blacklist that inserts by jti, such as a GuardianDb-style store). With the default no-op on_revoke callback, no session state is changed and the issue is not exploitable. Affected versions
1.0.0
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
+ 6 more Show less
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
1.0.0-beta.1
pre
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
1.0.0-beta.0
pre
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.14.5
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.14.4
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.14.3
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.14.2
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.14.1
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.14.0
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.13.0
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.12.0
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.11.1
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.10.1
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.10.0
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.9.1
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.9.0
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.8.1
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.8.0
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.7.4
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.7.2
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.7.1
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.7.0
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.6.3
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.6.2
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.6.1
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.6.0
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.5.2
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.5.0
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.4.1
patch
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev | ||
0.4.0
minor
1 CVE
CVE-2026-54894
EEF-CVE-2026-54894
GHSA-xqch-c77q-rgh5
Aug 01, 2026
Atom-table exhaustion denial of service in Guardian via unbounded atom creation from binary keys
High
Local
Low
None
None
SummaryAllocation 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_", 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. WorkaroundsDo 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. ConfigurationsOnly 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. Affected versions
0.1.0
0.1.1
0.10.0
0.10.1
0.11.1
0.12.0
0.13.0
0.14.0
0.14.1
0.14.2
0.14.3
0.14.4
+ 41 more Show less
0.14.5
0.14.6
0.2.0
0.3.0
0.3.1
0.4.0
0.4.1
0.5.0
0.5.2
0.6.0
0.6.1
0.6.2
0.6.3
0.7.0
0.7.1
0.7.2
0.7.4
0.8.0
0.8.1
0.9.0
0.9.1
1.0.0
1.0.0-beta.0
1.0.0-beta.1
1.0.1
1.1.0
1.1.1
1.2.0
1.2.1
2.0.0
2.1.1
2.1.2
2.2.0
2.2.1
2.2.2
2.2.3
2.2.4
2.3.0
2.3.1
2.3.2
2.4.0
Fixed in
2.4.1
References Updated Sep 08, 2026 · Source: OSV.dev |