CVE-2026-82579 Overview
CVE-2026-82579 is an infinite loop vulnerability [CWE-835] in the ash_ai library for the Elixir Ash framework. The flaw resides in AshAi.ToolLoop, which drives model-tool interactions for large language model (LLM) agents. An attacker who can influence a model's output, such as through prompt injection, can force the tool loop to hang and issue unbounded, repeated model requests. The issue affects ash_ai from version 0.6.0 before 1.0.0.
Critical Impact
Prompt-injected content can drive unlimited model calls, exhausting API quotas and compute budgets while stalling agent execution when max_iterations: :infinity is configured.
Affected Products
- ash-project/ash_ai versions 0.6.0 through < 1.0.0
- Elixir Ash framework applications integrating AshAi.ToolLoop
- LLM-backed services using ReqLLM.StreamResponse classification through ash_ai
Discovery Timeline
- 2026-08-31 - CVE-2026-82579 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-82579
Vulnerability Analysis
The vulnerability lives in the tool-call handling path of AshAi.ToolLoop. When a model response is classified as :tool_calls, ash_ai passes the calls through normalize_tool_calls/2 and unprocessed_tool_calls/2. Both filters can return an empty list. A call missing a valid tool name is dropped by normalization. A call reusing a tool_call_id that already has a result stored in conversation history is dropped as already processed.
When the filtered list is empty, the loop appends nothing to the message history and recurses with a byte-identical message list. The conversation state never advances. The same model request is re-sent on every iteration. Under the supported setting max_iterations: :infinity, the loop never terminates. With a finite budget, it consumes the entire iteration allowance while producing no progress.
Root Cause
The root cause is a missing terminal condition after tool-call filtering. The original code checked whether classification.type == :tool_calls, but did not check whether any calls survived normalization and deduplication. Because prompt-injected model output can deliberately re-emit a spent tool_call_id, an attacker can steer the model into producing responses that always filter to an empty list, keeping the loop stuck.
Attack Vector
Exploitation requires the ability to influence model output. In practice, this means indirect prompt injection through untrusted data ingested by the agent, such as retrieved documents, tool results, or user-supplied context. The attacker crafts content that causes the model to emit tool calls with reused tool_call_id values or invalid names. Every iteration then filters to an empty list, and ash_ai re-sends the request forever.
|> Map.put(:stream, chunks)
|> ReqLLM.StreamResponse.classify()
- if classification.type == :tool_calls do
- tool_calls =
+ tool_calls =
+ if classification.type == :tool_calls do
classification.tool_calls
|> normalize_tool_calls(chunk_tool_call_ids)
|> unprocessed_tool_calls(messages)
+ else
+ []
+ end
+ # An empty post-filter list means the model returned only invalid or
+ # already-processed tool calls, so `messages` would not advance.
+ # Recursing would re-send a byte-identical request forever (a
+ # no-progress loop, unbounded under `max_iterations: :infinity`), so
+ # treat it as terminal.
+ if tool_calls != [] do
messages =
append_tool_call_turn(
messages,
Source: GitHub Commit 53325fd
Detection Methods for CVE-2026-82579
Indicators of Compromise
- Repeated, byte-identical outbound requests from an ash_ai process to a configured LLM provider endpoint within a short window.
- Elevated LLM provider billing or rate-limit responses tied to a single agent session.
- Application logs showing continuous AshAi.ToolLoop iterations without new assistant or tool messages appended.
- Model responses referencing tool_call_id values already present in prior turns of the same conversation.
Detection Strategies
- Inspect running ash_ai deployments for the vulnerable version range 0.6.0 through < 1.0.0 in mix.lock or deps output.
- Add per-session counters that track tool-call iterations and alert when a threshold is exceeded without state advancement.
- Monitor LLM provider API call rates on a per-request-context basis and flag flatline conversations with growing call counts.
Monitoring Recommendations
- Emit telemetry from AshAi.ToolLoop with iteration counts, unique message-list hashes, and tool-call identifiers.
- Correlate spikes in LLM spend or 429 responses with specific agent sessions and untrusted data sources.
- Log and review any tool_call_id reuse across turns as a strong signal of prompt injection targeting this class of flaw.
How to Mitigate CVE-2026-82579
Immediate Actions Required
- Upgrade ash_ai to version 1.0.0 or later, which treats an empty post-filter tool-call list as terminal.
- Audit agents currently configured with max_iterations: :infinity and cap them until the patched version is deployed.
- Review recent LLM provider invoices and rate-limit events for signs of runaway loops.
Patch Information
The fix is committed in ash-project/ash_ai commit 53325fd and shipped in ash_ai1.0.0. Details are published in GitHub Security Advisory GHSA-rcx7-x2w5-mmc2, the Erlang Ecosystem Foundation CNA advisory, and OSV entry EEF-CVE-2026-82579.
Workarounds
- Set a conservative finite value for max_iterations instead of :infinity to bound worst-case cost.
- Reject or sanitize model output that references tool_call_id values already resolved in the current conversation.
- Isolate agent workloads behind provider-side rate limits and budget alerts to contain unbounded request storms.
# Update ash_ai to the patched release in mix.exs
# {:ash_ai, "~> 1.0"}
mix deps.update ash_ai
mix deps.get
mix compile
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

