Fetching from the wire…
Public story · 2026-09-02 · high
The Ash Framework's AI extension runs prompt strings through Elixir's template evaluator, so request data can become executable code.
Why now: The flaw is logged as CVE-2026-77956 in the 2026-09-02 vulnerability feed.
AshAi.Actions.Prompt, part of the Ash Framework's AI extension for Elixir, runs prompt content through EEx.eval_string, the language's template evaluator. The documented way to build a prompt is a function taking request input and context and returning prompt text. If that text includes anything from the request, an attacker can put Elixir code in a request field and have the server run it. NVD scored it 8.9 and logged it as CVE-2026-77956. No login required.
This sits next to a separate ash_ai bug in the same disclosure window, a DNS-rebinding issue. The two are unrelated mechanically. This one is worse: DNS rebinding needs a specific network setup to exploit, while this needs nothing but a prompt action that touches request data, which is most of them.
The root cause isn't Ash-specific. EEx.eval_string does exactly what a template evaluator is built to do: turn a string into running code. The mistake is upstream, treating a prompt as a plain string when part of it came from outside the app. Any prompt-templating layer in any language that concatenates user input and then evaluates the result, rather than just interpolating it as data, has this exact hole. Given how many teams are wiring LLM calls into existing web frameworks right now, I'd expect this pattern to turn up again somewhere else before the year's out.
If you're running ash_ai, check whether any prompt function pulls from action arguments and treat that as remote code execution until proven otherwise.
Each link below shares sources, entities, or timing with this story.
Versions through 2.5.8 pass unsanitized LLM-generated arguments straight to exec(), runpy.run_path() and subprocess.run() (NVD). This is Agno's second disclosure this month after CVE-2026-76832, a PythonTools path traversal via file_name, which points at the tool layer as a wh...
NVD published this today against ash_ai's MCP server. With the default allowed_origins: nil, origin_allowed?/3 accepts an origin when uri.host == conn.host and the forwarded scheme is https, but conn.host comes from the Host header and the scheme is read from raw x-forwarded-p...
NVD published this against kazuph/mcp-fetch through 1.6.3 on August 26. isSafeUrl reads the hostname from the parsed URL, which for yields the bracketed string, then tests it with net.isIP, which returns zero for a bracketed value. The entire private-address branch is skipped,...
NVD posted nine advisories on August 25, clustering into one shape: a local server assuming a browser can't reach it. PraisonAI validated MCP origins with request_origin.startswith(allowed) against a localhost allowlist, so an attacker-registered localhost.attacker.com passes...
The http_request and web_fetch agent tools in SiYuan before v3.8.1 validate only the safety-check resolution, so an attacker answers the guard lookup with a public address and the real lookup with an internal one (NVD). The paired CVE-2026-82233 is a path traversal in the asse...
StreamableHTTPServer.ServeHTTP and SSEServer.ServeHTTP accepted any request arriving over loopback regardless of the host it named (NVD). This one matters more than the individual server CVEs beside it because mcp-go is a widely used Go SDK, so every stdio-to-HTTP server built...
MindPattern daily
One email a day at 7 AM. Sources and a take on every story. Unsubscribe anytime.