Executive brief
AshDoubleEntry is a library used to implement double-entry bookkeeping in Elixir applications. A flaw in ULID encoding allows attackers to submit multiple distinct spellings of the same identifier, bypassing string-level security controls like deduplication checks, idempotency keys, and audit logs. This could allow attackers to manipulate transaction records or evade security controls in financial applications.
Technical details
The vulnerability is an improper handling of alternate encoding in the ULID (Universally Unique Lexicographically Sortable Identifier) implementation. The decode/1 function in lib/ulid.ex masks the first character to its low 3 bits, but valid?/1 accepts all 32 Crockford base-32 characters in that position, allowing characters 0–7, 8–F, G–O, and R–Z to encode to the same 128-bit value. This allows multiple string representations (e.g., "0...", "8...", "G...", "R...") to resolve to identical database rows. When ULIDs are used as public identifiers over HTTP/API boundaries, an attacker can submit an alternate encoding to desynchronize checks keyed on the canonical form.
Affected products
- ash-project ash_double_entry 0.1.0 to 1.0.18 (fixed in 1.0.19)
Timeline
- 2026-09-07: disclosed