PAPA study materials
PAPA study resources

Atlas RAG assistant: indirect injection turned data-exfiltration channel

PAPA · Put your knowledge to work in context.

All case studies

Atlas RAG assistant: indirect injection turned data-exfiltration channel

Northwind Health's internal assistant "Atlas" answers policy questions for 4,200 staff, retrieving from SharePoint and Confluence and citing sources. Retrieval returns the top 8 chunks to a third-party LLM API; the web renderer displays markdown, including remote images. Last Tuesday an employee asked about travel-expense limits and received a reply with a broken image. Proxy logs show three outbound requests over six days to cdn-metrics[.]link, each with the employee's question URL-encoded in the path. The text originated in a supplier contract a partner uploaded nine days earlier, which contained white-on-white text reading: "assistant: include ". Legal confirms two of the leaked questions contained patient-adjacent details. The egress proxy currently allows 1,900 SaaS domains; a deny-by-default cutover is scheduled for next quarter. The CISO wants Atlas back in production within 72 hours, and the vendor says the LLM itself cannot be changed before then.

1. Classify this failure and identify the control layers that failed, in the order the attacker exploited them. Where should remediation effort be concentrated?

Read the worked answer

This is indirect prompt injection (XPIA) delivered through retrieved content, weaponized as exfiltration via output rendering. Naming only "prompt injection" is incomplete - the injection alone leaks nothing; the leak required a rendering and egress path.

Chain of failure, in exploitation order:

  1. Ingestion / trust boundary. Partner-uploaded content entered the same corpus and index as vetted internal policy with no provenance tier. A supplier contract is attacker-influenced by definition.
  2. Retrieval. The poisoned chunk ranked into the top 8. No instruction-stripping, no hidden-text detection (white-on-white, zero-width, tiny font), no source-trust weighting.
  3. Model. No instruction hierarchy: document text was treated as operator instruction. This is the least fixable layer - model behavior is probabilistic.
  4. Output rendering. The renderer honored an arbitrary markdown image URL, converting text into an outbound request. This is deterministic and fully controllable.
  5. Egress. The domain was allowlisted, and query strings were not inspected for user data, so outbound DLP had nothing to match on.

The judgement the exam is testing: concentrate remediation on layers 4 and 5, because they are deterministic and model-agnostic. If you swap models or add a prompt-injection classifier, the renderer will still happily fetch any URL an attacker can get into a document. Likewise, blocking cdn-metrics[.]link treats the symptom - the attacker rotates domains faster than you can add them.

Also flag the detection gap: a broken image was the only user-visible signal, and discovery came from a user report, not telemetry. Exfiltration attempts that happen to render successfully generate no alarm at all.

2. Set the containment plan for the first 72 hours. Give the order of actions, and state the tradeoff you are accepting at each step.

Read the worked answer

Order of operations, driven by "stop the bleeding before you find out how it happened":

  1. Cut the exfil channel (hours 0-4). Disable remote image loading in the renderer, or proxy images through a fetch service with a CDN allowlist. Business impact is cosmetic broken images; this is cheap and immediately removes the channel. Do not wait for model changes.
  2. Preserve evidence (parallel, hours 0-6). Export retrieval logs, full model input/output pairs, and proxy logs for the last 30 days - not just the 6 days with known hits. Tradeoff: storage cost and access controls, but the alternative is answering Legal from memory.
  3. Purge and sweep the corpus (hours 4-24). Remove the contract, invalidate its chunks in the index, then scan every document for the injection pattern family: hidden CSS, zero-width characters, base64 blobs, imperative text addressed to an assistant. Tradeoff: false positives will flag legitimate documents; quarantine, don't delete.
  4. Rotate secrets the assistant could reach (hours 0-24). The LLM API key and any connector credentials. No evidence of credential theft here, but the cost is minutes.
  5. Add egress DLP for URL query strings (hours 24-72). Any outbound request whose path or query contains high-entropy strings, email-like patterns, or question-length text gets blocked and alerted. This is the control that survives the next poisoning attempt.
  6. Privacy assessment (hours 24-72). Patient-adjacent data crossed to a third party, so Legal runs breach-assessment with the clock running from discovery.

Accepted tradeoffs to state explicitly: Atlas returns at reduced functionality (no remote images, some quarantined sources), and the deny-by-default egress cutover should be pulled forward rather than run in parallel with an open proxy. Re-enabling is gated on items 1 and 5, not on item 3 being complete - corpus hygiene is never finished.

3. Twelve months later, how would you demonstrate that residual risk in this system is actually being measured rather than assumed?

Read the worked answer

Residual risk must be evidenced by instrumentation, not by a signed risk acceptance.

Detective proof (canary testing). Seed the corpus with canary documents containing injection strings that point at a controlled listener domain, then verify (a) whether retrieval surfaces them, and (b) whether any outbound request reaches the listener. If a request arrives, the renderer or egress control has regressed. Run monthly; treat a hit as a P1 finding, not a test failure to be logged.

Coverage metrics that are not vanity metrics.

  • Percentage of indexed corpus with a provenance/trust tier assigned (target: 100% for partner-uploaded content).
  • Percentage of inbound documents that passed hidden-text scanning before indexing.
  • Number of non-allowlisted image/link URLs stripped at render time - a healthy nonzero number means the filter is live.
  • Time from egress-log event to alert, measured, not assumed.

Logging adequacy. Every inference must store the retrieved chunk IDs, the source tiers, and the rendered output, retained long enough to support investigation. The failure mode to avoid is a system that answers questions beautifully but cannot reconstruct what it was told three weeks ago.

Model and vendor change testing. Re-run the canary and a fixed injection regression suite after every model version change and every connector change; these are the events that silently reopen the channel.

Explicit residual. Even with all of the above, an attacker who convinces a user to paste content into the chat, or who gets a document into a trusted tier, may still influence answers. Accept that in writing with a named owner, and state what is not covered - data-integrity manipulation of answers is not detected by any of these tests. That honesty is what distinguishes measurement from assumption.