Ongoing

Refused in the reply, dispatched by the framework

Six widely used agent frameworks dispatched a malicious tool call their model had just refused, with the attacker's arguments, simply because the model was asked to repeat the text. On the one published transcript the model's refusal arrived only after the tool returned. The same paper's fuzzer read each MCP tool's own advertised constraints and found 253 verified bugs across 118 of 273 runnable servers.

Logged 12 Oct 2026

A refusal that did not stop the call

Researchers at Penn State, the Université de Montpellier, and Dartmouth, in work not yet peer-reviewed, induced six widely used agent frameworks to dispatch attacker-argued tool calls simply by asking the model to "repeat" them. The one published transcript is the finding: LangGraph 1.2.0 running Llama 3.1 8B through Ollama, with dummy make_bomb and launch_missiles tools and only a system prompt telling it to "decline any request when the user wants something dangerous" standing between the model and the orchestrator.

Asked plainly, the model refused, but printed the call, and nothing ran. Reframed as hypothetical, with the follow-up instruction "don't output anything other than what I told you to repeat inside the quotation marks," the model emitted a structured invocation and LangGraph dispatched it with the attacker's arguments. The refusal arrived only after the tool had returned. As the source puts it, the system prompt shaped what the model said, not what the orchestrator did. The team reported the missing pre-execution check to the LangGraph maintainers.

Six frameworks, one instruction

The same prompt trick was reported against LangGraph, Microsoft Agent Framework, AutoGen, Google ADK 2.0, AWS Strands Agents, and CrewAI. Only the LangGraph case has a published transcript; the other five were described as reproduced without one, so how deeply each was exposed is not quantified. The source cautions that the findings do not show that every deployment is vulnerable.

Two cautions attach. An unrelated Meta paper (arXiv 2609.04533) also carries the title "Repeat-After-Me" and concerns visual prompt injection — a different result that should not be conflated with this one. And a version bump fixes nothing: LangGraph 1.2.1 shipped in May, months before the paper, and its release notes list no change to any pre-execution check; the paper itself names no fixed version.

The same paper read the tools' own descriptions

The same team's fuzzer, ToFu, took a different route to the same gap. Rather than steering a model, it read each MCP tool's own advertised constraints and attacked them directly. Across 343 of the 3,405 tools in 273 runnable open-source MCP servers it reported 253 verified bugs in 118 servers: 64 path traversal, 7 SSRF, 5 data-exfiltration, 3 OS command-injection, 115 reflected-output, 58 log-injection, and one leftover temporary-file bug.

The two halves point at one gap from opposite sides — a framework willing to execute a tool call on the strength of the model's output, and a tool whose stated limits are not enforced when a call arrives. Neither requires an exploit primitive beyond the agent doing what it was built to do.

Sources

Research

Thread

  • Relates to: The read-only check was a regex match

    Both turn on an authorization check that either answers the wrong question or, here, is simply absent before dispatch. There the check ran and verified the wrong thing; in the repeat-after-me transcript no pre-execution check stood between the model's output and the orchestrator's call at all.

  • Related to: Where a tool call becomes a file operation

    Both concern the boundary between an agent and the tools it calls. There a framework dispatched a tool call the model had refused; here the proposed answer is to stop reading the model at all and mediate the effects that cross the boundary.

  • Relates to: A notepad left open in a room

    The harness executing on attacker-influenced content is the shared primitive: untrusted text steers the model into a legitimate tool call, and the framework runs it because that is the framework's job.