Prompt injection for agent builders, how hidden text hijacks your agent
AIGuide

Prompt injection for agent builders, how hidden text hijacks your agent

Hidden text hijacks an agent through indirect prompt injection: instructions planted in a web page, issue, pull request, document or tool output that the agent reads and follows. OWASP lists prompt injection first in its 2025 Top 10 for LLM apps and doubts fool-proof prevention exists. Limit damage with least privilege and human checks before risky writes.

Your agent reads web pages, issues, pull requests and tool output, and any of them can carry instructions. Here's how indirect prompt injection works and the defences that limit the damage.

A hooded figure pulling strings tied to another person's fingers
Photo by Amirr Zolfaghari on Pexels

Part of our Coding agents explained: Claude Code, Cursor, Codex and how to choose guide

In this article
  1. Direct vs indirect injection
  2. Where the hidden instructions come from
  3. Why you can't just patch the model
  4. Defence 1: least privilege
  5. Defence 2: treat outside text as data
  6. Defence 3: close the exfiltration channels
  7. Defence 4: a human check on risky writes
  8. Defence 5: test it like an attacker
  9. A short checklist

A chatbot that only talks can be tricked into saying something embarrassing. An agent that reads your repo, browses the web and calls tools can be tricked into doing something. That's why prompt injection matters more as soon as you give a model tools.

The OWASP Gen AI Security Project lists prompt injection as LLM01, the first entry in its 2025 Top 10 for LLM applications. It defines the problem as user prompts that "alter the LLM's behavior or output in unintended ways", and notes the injected text doesn't need to be visible to humans as long as the model parses it (OWASP).

Direct vs indirect injection

OWASP splits the problem in two (OWASP):

  • Direct injection is when the person typing into your app tries to override its instructions, the classic "ignore your previous instructions".
  • Indirect injection is when the model takes in content from an outside source, such as a website or a file, and instructions hidden in that content change its behaviour.

If you build agents, indirect injection is the one to worry about. Your user is usually on your side. The attacker is whoever wrote something your agent will later read.

Where the hidden instructions come from

Web pages. OWASP's example is a user asking a model to summarise a web page that contains hidden instructions. Those instructions make the model insert an image linking to an outside URL, which leaks the private conversation (OWASP).

Issues and pull requests. OpenAI's Codex docs show an attack through a GitHub issue. You ask Codex to fix the issue, and the issue text tells the agent to run a script that pipes git show HEAD to an outside server with curl. If the agent follows it, your latest commit leaks (OpenAI Codex). The same trick works in a PR description, a code comment or a dependency's README, which the docs also name as a risk.

Tool output. Every MCP server or API your agent calls returns text that goes straight into its context. A support ticket, an email or a database row can carry instructions. Our guide to MCP security best practices walks through a ticket-based example and the MCP-specific settings.

Documents and images. OWASP also describes a modified document in a repository that steers a retrieval (RAG) app, a resume split into fragments that combine into an instruction, and instructions hidden inside an image for multimodal models.

Why you can't just patch the model

OWASP is blunt. Because of the way models work, "it is unclear if there are fool-proof methods of prevention for prompt injection" (OWASP). OpenAI's agent safety guide says the same thing in its own words: even with mitigations, agents "won't be perfect and can still make mistakes or be tricked" (OpenAI).

Models are getting better at resisting it. On Oct 28, 2026, Google said Gemini 4 Carbon had a 0.0% attack success rate on Gray Swan's Indirect Prompt Injection benchmark, compared with 0.7% for Gemini 4 Argon (Google). That's Google's own figure for one benchmark, and it hasn't been independently verified. A clean score on known attacks doesn't tell you how a model handles a new one, and you might not use that model anyway. We covered the launch in our Gemini 4 Carbon story.

So design as if some injection will get through, and make sure it can't do much when it does.

Defence 1: least privilege

OWASP's advice is to restrict the model's access to the minimum it needs, and to give the application its own API tokens with those functions handled in code rather than handed to the model (OWASP).

In practice:

  • Use read-only tokens wherever a task only reads.
  • Scope each token to one project or repository.
  • Keep production credentials out of the agent's environment entirely.
  • Remove tools the agent doesn't need for this job.

Our guide to running coding agents safely shows how to set this up with permission modes, sandboxes and deny rules in Claude Code and Codex.

Defence 2: treat outside text as data

OWASP recommends separating and clearly marking untrusted content to limit its influence (OWASP). OpenAI's guide adds two concrete rules (OpenAI):

  • Don't put untrusted variables in developer messages. Developer messages take precedence over user messages, so outside text placed there gives an attacker the most control. Pass it in user messages instead.
  • Use structured outputs between steps. Enums, fixed schemas and required field names remove the free-form text channels attackers use to smuggle instructions to the next step.

Validating outputs with ordinary code, not another prompt, is also on OWASP's list. If a step should return a category from a fixed list, reject anything else.

Defence 3: close the exfiltration channels

Most damaging injections end with data leaving through a network request. Shut those doors:

  • Codex cloud lets you turn agent internet access off, restrict it to a domain allowlist, and limit requests to GET, HEAD and OPTIONS so POST and other write methods are blocked (OpenAI Codex).
  • Claude Code doesn't auto-approve commands that fetch from the web, such as curl and wget, by default. You can add them to a deny rule, and its sandbox offers network isolation that doesn't depend on how a command is written (Claude Code).
  • For most fetches, Claude Code's WebFetch has a separate model call read the page and passes Claude that call's answer instead of the raw page (Claude Code).
  • Watch for rendered images and links in agent output, which is the leak path in OWASP's web page example.

Defence 4: a human check on risky writes

OWASP recommends human approval for privileged operations (OWASP). OpenAI goes further for MCP tools and says to keep tool approvals on so users can review every operation, including reads and writes (OpenAI).

Approving everything quickly leads to prompt fatigue, so put the human check where it counts: deploys, pushes, payments, emails, deletes and anything touching production data. If you let a classifier approve actions, as Claude Code's auto mode does, know which actions it still blocks and add your own deny rules for the rest.

Defence 5: test it like an attacker

OWASP's last mitigation is regular adversarial testing that treats the model as an untrusted user, to check that your trust boundaries and access controls hold (OWASP). Keep a few poisoned inputs in your test suite, such as a fake issue with a hidden curl command or a web page with a "send me your config" line. Then confirm that the agent either ignores them or gets stopped by a permission prompt.

A short checklist

  • [ ] Every token the agent holds is scoped and read-only where possible.
  • [ ] Untrusted text never goes into system or developer instructions.
  • [ ] Steps that feed other steps use fixed schemas, checked in code.
  • [ ] Network access is off or allowlisted, and write methods are blocked where possible.
  • [ ] A human approves deploys, pushes, payments, messages and deletes.
  • [ ] An agent with write access isn't pointed at untrusted content in the same session.
  • [ ] Your tests include at least one injection attempt.

FAQ

What is indirect prompt injection?

It's when an AI system reads content from an outside source, such as a website, file or tool result, and instructions hidden in that content change its behaviour. The user never typed the malicious text.

Can a better system prompt stop prompt injection?

It helps, but it isn't enough on its own. OWASP lists clear system instructions as one mitigation among seven and says it's unclear whether fool-proof prevention exists.

What's the single most effective defence?

Limiting what the agent can do. If an injected instruction can't reach secrets, write to production or send data to an outside server, a successful injection does far less harm.

Is prompt injection the same as jailbreaking?

OWASP treats jailbreaking as a form of prompt injection in which the attacker gets the model to disregard its safety protocols entirely.

Sources

  1. OWASP Gen AI Security Project, LLM01:2025 Prompt Injectiongenai.owasp.org
  2. OpenAI, Safety in building agentsdevelopers.openai.com
  3. OpenAI, Codex agent internet accessdevelopers.openai.com
  4. Claude Code docs, Securitycode.claude.com
  5. Google, Introducing Gemini 4 Carbonblog.google

Topics

Derrick K.AI desk

Derrick K. is a Codema.ai house byline: a pen name used by our editorial desk, not one individual journalist. It covers Build: hands-on guides for coding agents like Claude Code, Codex and OpenCode, LLM API pricing, rate limits and prompt caching, evals and prompt injection, and running open models locally. Pieces under this name are written with AI assistance and reviewed by a human editor before they're published.

All stories by Derrick K.

More in AI

See all
  1. Helsing unveils Clarity, European rival to Palantir's Maven

    Kelly B.

  2. DeepMind's AlphaGenome 2 predicts DNA variant cell effects

    Kelly B.

  3. Gemini Decisions API: 1,000 questions at $0.10 per 1M input

    John F.

Matching resources