Description
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.
Published: 2026-10-05
Score: 8.2 High
EPSS: < 1% Very Low
KEV: No
Impact: Denial of Service
Action: Apply Patch
AI Analysis

Impact

The flaw occurs because Ash stores attributes of type :atom as strings but compares them as strings. When a filter is applied to a public :atom attribute that is marked unsafe_to_atom?: true, the incoming filter value is coerced through Ash.Type.Atom using the default cast_input/2 implementation. That implementation converts the string to an Erlang atom via String.to_atom/1. Since atoms are never garbage collected, each distinct value to which a user can apply a filter generates a new permanent atom. Over time, an attacker can exhaust the BEAM atom table, causing the Erlang Virtual Machine to crash and result in a denial‑of‑service attack. The flaw affects not only Ash itself but also projects that expose such attributes, notably AshPaperTrail’s version_action_name field.

Affected Systems

All installed versions of Ash from 3.5.1 up to and including 3.34.2 are vulnerable. The issue was resolved in Ash 3.34.3 by adding a coerce/2 implementation that leaves the comparison value as a string, preventing unsafe atom internment. Users should verify the exact version they run and plan an upgrade if it lies in the affected range.

Risk and Exploitability

The CVSS score of 8.2 indicates high severity. EPSS data is currently not available, which means the likelihood of exploitation cannot be quantified but the lack of mitigation in earlier releases leaves systems susceptible. The attack vector is inferred to be network‑based, as an attacker can supply filter values through any public endpoint that accepts the :atom attribute, such as AshPaperTrail’s version resources. Once the atom table is saturated, the entire node process will terminate, causing a denial‑of‑service.

Generated by OpenCVE AI on October 5, 2026 at 21:00 UTC.

Remediation

No solution or workaround provided in the CVE record.

OpenCVE Recommended Actions

  • Upgrade Ash to version 3.34.3 or later, which implements a safe coerce/2 that prevents atom internment during filtering.
  • If an upgrade cannot be performed immediately, review the configuration of all :atom attributes and set unsafe_to_atom? to false or remove the attribute from publicly filterable endpoints.
  • As a temporary workaround, replace unsafe_to_atom? usage with explicit string comparison logic or sanitize input values to limit the number of distinct atoms created.

Generated by OpenCVE AI on October 5, 2026 at 21:00 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Tue, 06 Oct 2026 14:30:00 +0000

Type Values Removed Values Added
Metrics ssvc

{'options': {'Automatable': 'no', 'Exploitation': 'none', 'Technical Impact': 'partial'}, 'version': '2.0.3'}


Mon, 05 Oct 2026 19:30:00 +0000

Type Values Removed Values Added
Description 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.
Title Filtering an :atom attribute with unsafe_to_atom? can exhaust the BEAM atom table in Ash
First Time appeared Ash-project
Ash-project ash
Weaknesses CWE-770
CPEs cpe:2.3:a:ash-project:ash:*:*:*:*:*:*:*:*
Vendors & Products Ash-project
Ash-project ash
References
Metrics cvssV4_0

{'score': 8.2, 'vector': 'CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N'}


cve-icon MITRE

Status: PUBLISHED

Assigner: EEF

Published:

Updated: 2026-10-06T13:41:22.142Z

Reserved: 2026-09-24T09:15:02.216Z

Link: CVE-2026-94201

cve-icon Vulnrichment

Updated: 2026-10-06T13:41:16.744Z

cve-icon NVD

Status : Deferred

Published: 2026-10-05T20:17:28.693

Modified: 2026-10-06T15:03:59.427

Link: CVE-2026-94201

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-10-06T00:15:04Z

Weaknesses
  • CWE-770

    Allocation of Resources Without Limits or Throttling