# CVE-2026-81638: ash-project ash_double_entry ULID encoding bypass

Source: https://junglewise.ai/threats/cve-2026-81638-ash-project-ash-double-entry-ulid-encoding-bypass  
Publisher: Junglewise Threat Intelligence, https://junglewise.ai/threats  
Published: 2026-09-07. Updated: 2026-09-26  
License: CC BY 4.0 with a link back

CVE-2026-81638 · Severity: info · Published 2026-09-07

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.

Vendors: [Ash-Project](https://junglewise.ai/threats/vendors/ash-project).

## Quick answers

**Is CVE-2026-81638 exploited in the wild?** No. Junglewise Threat Intelligence has no report of CVE-2026-81638 being exploited in the wild.

**How severe is CVE-2026-81638?** Informational severity, published 7 September 2026.

**Which products and versions are affected?** Ash-Project Ash Double Entry 0.1.0 to 1.0.18 (fixed in 1.0.19).

**Is there a fix for CVE-2026-81638?** No fixed version is recorded yet. Check the vendor's advisory in the references below. If you run it, Junglewise drafts a mitigation that fits your setup and applies it once you approve, with senior security engineers behind it.

**How is CVE-2026-81638 attacked?** It is attacked over the network, in a software library.

**Am I affected by CVE-2026-81638?** Check whether you run Ash-Project Ash Double Entry at an affected version. Junglewise does that check for you around the clock: connect your code, cloud and domains, and it matches new vulnerabilities like this one against what you actually run and tells you when one reaches you.

## 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

## References

- [https://repo.hex.pm/](https://repo.hex.pm/)
- [https://github.com/](https://github.com/)
