Filtering an :atom attribute with unsafe_to_atom? can exhaust the BEAM atom table in Ash
## Summary Ash stores `:atom`-typed attributes as strings and compares them as strings. When such an attribute is referenced in a filter, the comparison value is coerced through `Ash.Type.Atom`. Because the type defined no `coerce/2` callback, coercion fell back to the default (`cast_input/2`), which calls `String.to_atom/1` when the attribute is configured with the `unsafe_to_atom?: true` constraint. Filtering such an attribute with attacker-controlled strings therefore interned a new, permanent atom for every distinct value. Atoms are never garbage collected and the BEAM caps the atom table, so an actor who can supply filter values for a public, filterable `:atom` attribute declared with `unsafe_to_atom?: true` can exhaust the atom table and crash the node (denial of service). AshPaperTrail is a notable example: its version resources expose a public, filterable `version_action_name` atom attribute with `unsafe_to_atom?: true` by default. The fix adds a `coerce/2` to `Ash.Type.Atom` that never interns atoms — a comparison value is left as a string, since the type is stored and compared as a string. Setting the attribute from action input (`cast_input/2`, which still honors `unsafe_to_atom?`) is unchanged. This issue affects ash: from 3.5.1 before 3.34.3. ## Configurations Reachable only when an application exposes a public, filterable `:atom` attribute declared with the `unsafe_to_atom?: true` constraint, and an actor can supply filter values for it (for example through AshGraphql, AshJsonApi, or `Ash.Query.filter_input/2`). AshPaperTrail's version resources ship such an attribute (`version_action_name`) by default.
describes (1)
Related CVEs.
| ID | severity | exploitable | ||
|---|---|---|---|---|
| CVE-2026-94201US | — | — | ||
Ash stores :atom-typed attributes as strings and compares them as strings. When such an attribute is referenced in a filter, the comparison value is coerced through Ash.Type.Atom.… | ||||
references
External citations — patches, advisories, analysis.
Advisories like this name the exposed products attackers go after on your perimeter. See what is exposed on your perimeter with a free passive scan.
Free scan