EEF-CVE-2026-69659 CVE-2026-69659 GHSA-j35q-v8h8-7mwq
Memory exhaustion via unbounded deserialization of keyset pagination cursors in Ash.Page.Keyset
- Severity
- 0.0 / 10
- Medium · CVSS 4.0
- Exploit chance (EPSS)
- 0.36%
- Chance of exploitation in the next 30 days. Higher than 29.59% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-502 Deserialization of Untrusted Data
- Fix
3.31.1- Upgrade ash to this version or later
Description
Summary
Uncontrolled Resource Consumption vulnerability in ash-project ash allows an attacker to exhaust the memory of the node via a crafted keyset pagination cursor.
Read actions with keyset pagination deserialize the client-supplied page[:after] or page[:before] cursor in decode_values/2 in lib/ash/page/keyset.ex, which base64-decodes the value and passes it to :erlang.binary_to_term/2 without bounding its size. The Erlang external term format supports zlib-compressed payloads, which the decoder inflates transparently, so a cursor of a few kilobytes can allocate tens of megabytes of heap in a single call. Ash itself only ever encodes cursors uncompressed, so the decoder accepts a term shape its encoder never produces. Concurrent requests aggregate these allocations and can terminate the node.
This issue affects ash: from 1.17.0 before 3.31.1.
Configurations
A read action must declare keyset? true in its pagination block, and the application must pass a client-supplied value as the :after or :before page option.
Affected versions
Hex
| Package | Vulnerable | Fixed in |
|---|---|---|
| ash | >= 1.17.0, < 3.31.1 |
3.31.1 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
ash Hex → 3.31.1
- mix
{:ash, "~> 3.31.1"} # then: mix deps.update ash
Severity breakdown
CVSS 4.0 0.0
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
- Attack vector
- Local
- Attack complexity
- Low
- Attack requirements
- Present
- Privileges required
- None
- User interaction
- None
- Confidentiality (vulnerable system)
- None
- Integrity (vulnerable system)
- None
- Availability (vulnerable system)
- High
- Confidentiality (subsequent systems)
- None
- Integrity (subsequent systems)
- None
- Availability (subsequent systems)
- None
CVSS 3.1 5.5
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
- Attack vector
- Local
- Attack complexity
- Low
- Privileges required
- Low
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Weakness
CWE-502: Deserialization of Untrusted Data
The product deserializes untrusted data without sufficiently ensuring that the resulting data will be valid.
How to prevent it
- Architecture and Design, Implementation: If available, use the signing/sealing features of the programming language to assure that deserialized data has not been tainted. For example, a hash-based message authentication code (HMAC) could be used to ensure that data has not been modified.
- Implementation: When deserializing data, populate a new object rather than just deserializing. The result is that the data flows through safe input validation and that the functions are safe.
- Implementation: Explicitly define a final object() to prevent deserialization.
- Architecture and Design, Implementation: Make fields transient to protect them from deserialization. An attempt to serialize and then deserialize a class containing transient fields will result in NULLs where the transient data should be. This is an excellent way to prevent time, environment-based, or sensitive variables from being carried over and used improperly.
- Implementation: Avoid having unnecessary types or gadgets (a sequence of instances and method invocations that can self-execute during the deserialization process, often found in libraries) available that can be leveraged for malicious ends. This limits the potential for unintended or unauthorized types and gadgets to be leveraged by the attacker. Add only acceptable classes to an allowlist. Note: new gadgets are constantly being discovered, so this alone is not a sufficient mitigation.
- Architecture and Design, Implementation: Employ cryptography of the data or code for protection. However, it's important to note that it would still be client-side security. This is risky because if the client is compromised then the security implemented on the client (the cryptography) can be bypassed.
- Operation: Use an application firewall that can detect attacks against this weakness. It can be beneficial in cases in which the code cannot be fixed (because it is controlled by a third party), as an emergency prevention measure while more comprehensive software assurance measures are applied, or to provide defense in depth [REF-1481].
References
Advisories
Fixes and patches
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| EEF-CVE-2026-96581 An upsert on the primary key in Ash ignores attribute multitenancy, so one tenant can read, overwrite and take over another tenant's records | Not rated yet | Also affects ash |
| EEF-CVE-2026-114214 Loading a through relationship with a limit of 1 in Ash ignores the through path and returns unrelated destination records | Not rated yet | Also affects ash |
| EEF-CVE-2026-101028 Ash.count, Ash.exists and Ash.aggregate skip related resources' read policies in filters and sorts | Not rated yet | Also affects ash |
| EEF-CVE-2026-94201 Filtering an :atom attribute with unsafe_to_atom? can exhaust the BEAM atom table in Ash | Not rated yet | Also affects ash |
| EEF-CVE-2026-93477 Private action arguments can be set by user input on the bulk destroy and bulk update paths in Ash | Not rated yet | Also affects ash |
| EEF-CVE-2026-86338 Ash field policies do not filter-nil forbidden calculations and aggregates, enabling an information-disclosure oracle | Not rated yet | Also affects ash |
| EEF-CVE-2026-82752 Ash string length constraints count graphemes, so a combining-mark string of any size passes max_length | Not rated yet | Also affects ash |
| EEF-CVE-2026-82747 Ash.Policy.Authorizer returns records denied by a runtime read policy to any actor | Not rated yet | Also affects ash |
Credits: Jisung Chae, Jonatan Männchen / EEF, Zach Daniel
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor