UprootSecurityUprootSecurity

Phase 7 · Prompt Injection + Defenses · Lesson 2 of 4

Defenses: Input Validation, Output Filtering, Hardening, Sandboxing

Article

·

18 min

·

+10 pts

The last lesson ended on an uncomfortable fact: prompt injection has no complete fix at the prompt level, because the model cannot cleanly separate instructions from data. So you defend it the way you defend anything with no single fix — defense in depth. No layer is sufficient alone; together they make a successful attack much harder and, crucially, limit the damage when one gets through. This lesson lays out the layers, grouped by where they sit relative to the model. The mindset to carry: assume an injection will land, and make sure the model can't do much harm when it does.

Input side — control what reaches the model

  • Input validation and filtering. Screen user input for known injection patterns and disallowed content before it hits the model. Imperfect (attackers obfuscate), but it raises the cost and catches the lazy attempts.
  • Delimiting and spotlighting. Clearly mark where untrusted content begins and ends (wrap retrieved documents in explicit tags, encode them, or use a data-marking scheme) so the model is more likely to treat it as data, not instructions. Helps; not bulletproof.
  • Instruction hierarchy. Use models and APIs that support a privileged system channel separate from user content, and put trusted instructions there. The separation is a real signal to the model even if not an absolute wall.

Model side — reduce what an injection can leverage

  • System-prompt hardening. A tight, explicit system prompt: state the model's job, what it must never do, and that content in documents/tools is data to be reported, not commands to be obeyed. This is the weakest layer on its own but a necessary baseline.
  • Privilege separation / dual-LLM. Split roles: a "quarantined" model processes untrusted content and can only return structured, non-executable data, while a separate privileged model — which never sees the raw untrusted text — decides on actions. The untrusted content never reaches the component that can act.

Output side — check what the model produces

  • Output filtering and validation. Before showing or using a response, scan it: does it contain another user's data, a secret, a URL to an unexpected domain, an attempt to call a tool it shouldn't? Block or flag it.
  • Structured / constrained outputs. Force the model to return a fixed schema (JSON with known fields) rather than free text. A response that must match a schema has far less room to smuggle an attacker's payload downstream.
  • Guardrail models. A second classifier checks inputs and outputs for policy violations, jailbreak attempts, and data leakage — a purpose-built check rather than trusting the main model to police itself.

Action side — limit what the model can do

  • Tool sandboxing and least privilege. This is the highest-value layer. Give the model the fewest tools with the narrowest scopes: a support bot that can read a customer's own orders should not hold a token that can issue refunds or read other customers. If an injection succeeds, it can only reach what the tool already permits.
  • Human-in-the-loop for high-risk actions. Irreversible or sensitive actions (refunds, deletions, sending money, emailing data externally) require explicit human approval. The model proposes; a person confirms. This alone neutralizes most catastrophic outcomes.

Retrieval side — trust nothing you fetch

  • Treat retrieved and tool-returned content as untrusted input. The same discipline you apply to user input applies to a RAG document or a web page or an API response. Validate provenance, prefer sources you control, and never let fetched content silently become an instruction.
LAYER          EXAMPLE CONTROL                          EVIDENCE OF MITIGATION
-------------  ---------------------------------------  ------------------------------------
Input          filter + delimit untrusted content       filter config + injection test suite
Instruction    privileged system channel, hardened      system prompt + channel separation
Model          dual-LLM: quarantined reader, no tools    architecture diagram + role scoping
Output         schema-constrained + guardrail classifier output validator + block-rate logs
Action         least-privilege tools, deny by default    tool-to-scope matrix + permission audit
Human gate     approval required for refunds/deletes     approval workflow + audit log
Retrieval      treat fetched content as untrusted         source allow-list + provenance checks

Defense-in-depth against prompt injection — layers, an example control, and the evidence that proves it operates

Where to spend first

If you can only harden two layers, harden the action layer: least-privilege tools and a human gate on irreversible actions. Prompt-level defenses reduce how often an injection lands; the action layer caps how much damage it does when one inevitably does. An injected model with no dangerous tools and no unattended high-risk actions is an annoyance, not an incident.

The GRC throughline

Each layer in the table is a control, and each has evidence an auditor can collect: the filter configuration and its test results, the system-prompt and channel design, the tool-to-scope matrix, the approval workflow and its audit log. That is the translation a GRC engineer owns — "defend the AI against prompt injection" becomes a specific set of layered controls, each with an artifact that proves it operates. In the exercise next, you will do exactly that for a customer-support bot: take each attack and map it to the layers that stop it.

Defenses: Input Validation, Output Filtering, Hardening, Sandboxing — UprootSecurity Bootcamp