BTC
ETH
SOL
BNB
GOLD
XRP
DOGE
ADA
Back to home
Security

[HIGH] Security Advisory: Ash.Type.Module.cast_input/2 atom exhaustion via unchecked Module.concat allows BEAM VM crash (ash)

Ash, the Elixir framework for building resources and APIs, has a critical vulnerability in its built-in :module type handler.

Ash, the Elixir framework for building resources and APIs, has a critical vulnerability in its built-in :module type handler. Attackers can feed it unique strings starting with "Elixir.", forcing the creation of new Erlang atoms without checks. These atoms pile up until the BEAM VM’s atom table hits its 1,048,576-entry limit, crashing the entire process. Any Phoenix app or service using Ash with public :module-typed fields faces full denial of service from a simple request loop.

This isn’t theoretical. The bug lives in Ash.Type.Module.cast_input/2 (lines 105-113 in lib/ash/type/module.ex). It blindly calls Module.concat([value]) on user input like "Elixir.Attack123", creating a permanent atom :"Elixir.Attack123". Only afterward does it check if the module loads via Code.ensure_loaded?. By then, the atom sticks around forever—Erlang doesn’t garbage-collect them.

The Vulnerable Code Path

Here’s the offender:

def cast_input("Elixir." <> _ = value, _) do
  module = Module.concat([value])  # Creates new atom unconditionally
  if Code.ensure_loaded?(module) do
    {:ok, module}
  else
    :error  # Atom already created and persists
  end
end

The safer path for non-"Elixir." strings uses String.to_existing_atom/1, which errors out if the atom doesn’t exist—no new atom created. Same issue repeats in cast_stored/2 (line 141), hittable during database reads if attackers previously wrote junk to the column.

Ash documents :module types for attributes like custom handlers, making this a supported pattern. Consider a resource like this:

defmodule MyApp.Widget do
  use Ash.Resource, domain: MyApp, data_layer: AshPostgres.DataLayer

  attributes do
    uuid_primary_key :id
    attribute :handler_module, :module, public?: true
  end

  actions do
    defaults [:read, :destroy]
    create :create do
      accept [:handler_module]
    end
  end
end

Public ?: true exposes it via API. Attackers hammer Ash.create/2 with unique payloads.

Exploitation in Practice

Loop this 1.1 million times via script or HTTP flood:

for i <- 1..1_100_000 do
  Ash.Changeset.for_create(MyApp.Widget, :create, %{
    handler_module: "Elixir.Attack#{i}"
  })
  |> Ash.create()
end

Each call spawns a new atom. Around iteration 1,048,576, BEAM throws system_limit and dies. No supervision tree saves you—the VM is toast. Restart required.

BEAM atoms power everything: PIDs, module names, binaries under 256 bytes. Default limit: 1,048,576. You can bump it with +t flag (e.g., +t 2M), but that’s no fix—attackers just need more requests. Past vulns like Cowboy’s atom leak (CVE-2019-9111) hit similar notes; Elixir devs know this risk.

Ash powers real apps—think admin panels, CMS, event sourcing. If your API accepts :module inputs without validation, you’re exposed. Even read-only endpoints trigger via cast_stored if DB holds attacker data.

Impact and What to Do

Full VM crash means downtime for all services on that node. In clusters, one compromised endpoint takes one instance offline; scale suffers. No data loss usually—persisted safely—but availability tanks. CVSS? High: 7.5+ for network DoS.

Fair to Ash: They support dynamic modules legitimately. But skipping to_existing_atom here is sloppy. Fix: Swap Module.concat for String.to_existing_atom(value) in a try/rescue ArgumentError, mirroring the other path. Audit all :module fields; restrict to allowlists. Set public?: false unless needed. Monitor atom count via :erlang.system_info(:atom_count) and :atom_limit.

Broader lesson: User input touching atoms is poison in BEAM land. Frameworks must gate it hard. Check your Ash version—pre-fix exposes you. Update fast, or firewall those fields. This matters because Elixir’s uptime rep takes hits from DoS like this.

April 1, 2026 · 3 min · 9 views · Source: GitHub Security

Related