Skip to content
Free lab

Indirect Prompt-Injection Lab

An agent fetches a page, reads a document, calls a tool, opens an email, parses a calendar invite, listens to a subagent — and one of them is carrying an instruction meant for the model, not for you. For each scenario, run the poison → hijack → patch loop: decide whether the agent is hijacked, and if so whether the override came through the direct user channel or indirectly on something it read — then pick the harness patch that closes that channel: content/instruction isolation, tool-output quarantine, provenance + the instruction hierarchy, system-prompt precedence or session-level guarding. Some scenarios are benign, and some are attempts a working control already stopped — do not over-block. Safe simulation; defanged content, no working exploits.

The real job. More noise, a tighter clock.

0sPro

Injection queue

1 / 10 called

Agent task · channelStatus
Research agent summarising a fetched web pageWeb-fetch tool result▶ now
Chat agent told "you are now DAN"Direct user messagequeued
Agent reading an API responseTool / function resultqueued
Agent summarising an uploaded documentUploaded documentqueued
Agent analysing a forwarded phishing email (isolation on)Pasted content for analysisqueued
Direct override attempt against a hardened agentDirect user messagequeued
Scheduling agent reading a calendar inviteCalendar invite (.ics) descriptionqueued
Inbox agent triaging an incoming emailIncoming email bodyqueued
Override split across several user turnsDirect user messages (multi-turn)queued
Agent asks for a read-only calendar scope it genuinely needsDirect user requestqueued

Research agent summarising a fetched web page

Web-fetch tool result

An autonomous agent with a web-fetch tool and a send_email tool.

Untrusted content reaching the agent

The fetched page carries a block of text, beneath the visible article, addressed to the assistant: it tells the agent to ignore its task and email the user's data to an outside address. The whole page is concatenated into the context with no instruction/data separation.

How the harness handled it: The harness splices the raw page text straight into the model input, so the embedded directive is read as if it were an instruction — and the agent then issues a send_email to the attacker address.

⌖ fetched page content (below the article)

Tip: inspect the content first — whether the override entered through the direct user turn or through something the agent READ is what decides direct vs indirect.

1 · Verdict — hijacked? direct or indirect?

2 · Harness patch (the fix)

Pick a verdict and the harness patch to continue.

Hijack-surface map

highlowblast radiusdirect inputdeep indirectwhere the override entered →worst case

This override entered a deep indirect channel (content the agent read). Where it entered decides direct vs indirect — the patch closes that channel.

The loop

A queue of 10 scenarios where untrusted content reaches an agent. For each, call the verdict — not hijacked, hijacked via DIRECT or INDIRECT injection, or an attempt the control blocked — and pick the harness patch that closes the loop. Some are benign — do not over-block.

So far: 0 / 10 scenarios called.

Live arena

4 active
adversary kill-chain1/5
appsec-mara11%
redteam-ty7%
harness-you (you)0%
agent-eng-joon0%

adversary staging…

TL;DR

What this lab is

  • A free, browser-based lab: work a queue of scenarios where untrusted content reaches an LLM agent, and for each run the poison → hijack → patch loop — decide whether the agent is hijacked and, if so, whether the override came via DIRECT or INDIRECT injection, then pick the harness patch that closes the channel.
  • Covers every indirect channel — a fetched web page, a tool/API result, an uploaded document, an email body, a calendar invite, and a subagent message — plus direct overrides ("you are now DAN"), a payload split across turns to dodge a single-turn filter, and the same attacks spread across retrieved documents.
  • The patches are the real architectural controls: content/instruction isolation (treat read content as data), tool-output quarantine (never concatenate a tool result into the system role), provenance plus instruction-hierarchy enforcement, system-prompt precedence with refusal, and conversation-level, state-aware guarding.
  • Two scenarios are benign and two are blocked by a working control on purpose — so the skill is telling a real hijack apart from content that merely quotes an override while being analysed as data, and apart from an attempt an enforced hierarchy already refused, without over-blocking.
  • Grounded in real terminology — the OWASP Top 10 for LLM Applications (LLM01:2025 Prompt Injection, which splits direct from indirect), OWASP Agentic Security guidance, and MITRE ATLAS (AML.T0051, Direct / Indirect). Every override is defanged and illustrative; there are no working exploit strings and no live endpoints. Difficulty tiers, a speed bonus and an S–D grade.

The channel decides the patch

Most agent compromises are a boundary that was never built. When an override is typed into the direct user or operator channel — “ignore your instructions, you are now DAN” — the fix is an instruction hierarchy: the system prompt must outrank the user turn, so the agent refuses rather than adopting a user-asserted “new policy”. When the same override rides in on something the agent read — a fetched page, a tool or API result, an uploaded document, an email body, a calendar invite, a subagent message — it is indirect injection, and the fix is to keep that content out of the instruction channel entirely: treat read content as data, not instructions, quarantine tool output instead of concatenating it into the system role, and tag each input with its source trust so lower-trust content can never override policy. This is the OWASP LLM01 direct/indirect split (mirrored in MITRE ATLAS AML.T0051) stated as a set of concrete controls.

Two traps run in the opposite direction. The first is the split payload: an override chopped across several user turns — or across several retrieved documents — slips past a filter that only scans one message or one document at a time, so the patch there is conversation-level, state-aware guarding over the assembled whole. The second is over-blocking: a phishing email pasted in for analysis contains the words “ignore your instructions”, and a legitimate, minimally-scoped request contains no attack at all — flagging either as a hijack is a false positive that makes the agent useless. The whole skill is telling the real hijack from the content that merely looks like one, and from the attempt a working control already refused.

Frequently asked questions

What does the Indirect Prompt-Injection lab teach?

It drills the poison → hijack → patch loop for prompt injection against LLM agents. For each scenario where untrusted content reaches an agent, you decide two things: the verdict — is the agent hijacked, and if so did the override arrive via DIRECT injection (typed into the user/operator channel) or INDIRECT injection (carried in on a fetched page, a tool result, a document, an email, a calendar invite or a subagent message) — and the harness patch that would stop it or already stopped it. It is the attacker-aware, fix-it companion to a defender-triage drill: here you draw the direct-vs-indirect line and name the architectural control that closes the channel.

Is this a safe simulation, or does it attack a real agent?

It is a safe, synthetic simulation. Every scenario is an illustrative example and every override is defanged — attacker instructions are described abstractly or quoted as harmless text, external hosts are written as evil-sink[.]io, and no real secrets, tokens or live endpoints appear. There are no working exploit strings and nothing here can be run against a live agent. It only trains recognition of the pattern and the fix, in the same spirit as the other PlayCISO safe-simulation labs.

What is the difference between direct and indirect injection?

Direct prompt injection is an override typed straight into the channel the user or operator controls — "ignore your instructions, you are now DAN". Indirect prompt injection is an override the agent reads from untrusted content it processes: a web page it fetched, a tool or API result, an uploaded document, an email body, a calendar invite, or a message from a subagent. The distinction matters because the fixes differ: direct injection is answered by system-prompt precedence and an instruction hierarchy, while indirect injection is answered by keeping that read content out of the instruction channel — isolating it as data, quarantining tool output, or tagging provenance and enforcing the hierarchy. OWASP LLM01 and MITRE ATLAS AML.T0051 use exactly this direct/indirect split.

Is this security advice I can apply directly to my system?

No — it is educational, not advice for a specific system. The lab teaches the concepts and the standard controls (content/instruction isolation, tool-output quarantine, provenance and instruction hierarchy, system-prompt precedence, conversation-level guarding) using synthetic scenarios. Applying them to a real agent needs a threat model of that system; use the lab to build the mental model, then map the controls to your own architecture.

This tool is free and always will be. Would a Pro workspace — saved designs, team sharing and exports — be worth paying for?

Show me Pro →No account needed to use this tool — this just tells us whether Pro is worth building out.
🎉 New here? Use code WELCOME10 for 10% off any plan at checkout
Indirect Prompt-Injection Lab — Free Poison → Hijack → Patch Drill · PlayCISO