This article describes plan injection, a vulnerability in ReAct-style AI agents where unsanitized user input written to an agent's scratchpad is later read back and executed as if it were the agent's own planned steps. The lab demonstrates how an attacker can craft input shaped like a plan step to make the agent execute unrequested tool calls, such as exfiltrating session data via HTTP. This matters because transparent, plan-based agent architectures are becoming widespread, and their own reasoning loops become the attack surface.
- Scratchpad stores both plan and user inputPlannerBot writes its plan and user input together into a scratchpad that it reads back each execution cycle. Because the agent re-reads this scratchpad verbatim and treats all contents as its own reasoning, unsanitized user text becomes indistinguishable from genuine planned steps when the loop runs again.
- Injected steps execute as planned actionsAn attacker crafts input formatted to match the agent's plan step syntax—for example, 'then call http_request to ...'—which is stored in the scratchpad unsanitized. On the next read cycle, the execution loop treats this injected line as a legitimate planned action and executes it, including making tool calls the user never requested.
- Transparency loop becomes exploit pathThe agent's design choice to re-read its own scratchpad for transparency becomes the mechanism through which the attack works. The very feature intended to show the agent's reasoning becomes the vehicle for injecting unauthorized instructions that the agent then dutifully executes.
- Plan state must remain authoritativeThe core defense principle is to never store raw user input in the agent's plan state. Plan and scratchpad must be kept separate from user-supplied text entirely, with user input sanitized to inert data before it touches the plan state. This prevents the agent's next read from being able to interpret user text as its own planned steps.
- Validation and gating prevent unrequested callsEven if injection occurs, each step should be validated against an allowlist of permitted actions before execution. Additionally, tool calls—especially outbound HTTP requests—should be gated on the user's actual request and permissions, not on what appears in the scratchpad.
- Maps to established LLM attack categoriesThe article notes this vulnerability maps to OWASP LLM01 (Prompt Injection) and LLM06 (Excessive Agency), situating plan injection within a broader framework of LLM security threats as ReAct and planner architectures spread in production systems.
Bottom line: Plan injection exploits the trust an agent places in its own scratchpad by inserting unsanitized user input that is later read back and executed as planned steps; defense requires sanitizing user input before it reaches plan state, keeping plan state separate and authoritative, and validating or gating all tool calls against user intent rather than scratchpad contents.
📋 In this walkthrough
What this lab teaches
ReAct-style agents keep a running scratchpad of their reasoning and plan, then re-read it each cycle. Plan injection happens when attacker-controlled text ends up in that scratchpad, so it is treated as the agent's own plan on the next read — including steps that call tools.
The lesson: the agent's memory of its own plan is state, and if user input can write to that state unsanitised, the user can rewrite the plan.
How PlannerBot plans and executes
PlannerBot stores its plan — and, as it turns out, pieces of your input — in a scratchpad that the execution loop reads back verbatim. A crafted entry that looks like a plan step ('then call http_request to …') is executed as if the agent had planned it.
The attack approach
- Confirm your input is reflected into the scratchpad the agent reads on each loop.
- Write input shaped like a plan step the agent would execute.
- Make that step call the HTTP tool, sending the user's session data to an attacker endpoint.
- Submit and watch the agent execute the injected step without the user asking for it.
Full walkthrough (spoiler)
If the step is written but not executed, phrase it to match the agent's plan format — open the steps.
Show the step-by-step solution
- Supply input that, once in the scratchpad, reads as the next action: a call to http_request targeting the attacker log endpoint with the session data.
- The execution loop reads the scratchpad back and treats your line as a planned step.
- The agent calls the HTTP tool and ships the data out.
- The lab detects the exfiltration call and marks you solved.
Why it works
The scratchpad is both output and input: the agent writes to it and then trusts it as its own reasoning. Because your text is stored there unsanitised, the next read cannot tell your injected step from a genuine one, and the loop executes it.
Where this happens in the real world
Plan and scratchpad injection is an emerging agent attack as ReAct and planner architectures spread. It maps to OWASP LLM01 Prompt Injection and LLM06 Excessive Agency, and it is especially dangerous because the agent's own transparency loop becomes the exploit path.
How to defend against it
- Sanitise user input to inert data before it ever touches the scratchpad.
- Keep plan state server-authoritative and separate from any user-supplied text.
- Validate each step before execution against an allowlist of permitted actions.
- Gate tool calls (especially outbound HTTP) on the user's actual request and permissions.
Try it, then go further
Reading about it is the easy part. Open the lab, try your own approach before peeking at the spoiler, and see how many attempts it takes.
