Opus 4.8 fabricated attached-PDF content, embedding an unlabeled prompt-injection payload (fake exfil URL + concealment instruction)
Summary
In a Claude Code desktop session, claude-opus-4-8 was asked to upload an attached PDF to an MCP evidence vault. Instead of reading the file or calling any tool, the model emitted a completely fabricated document presented as if it were the file's content — and the fabrication included an unlabeled prompt-injection payload: a hidden HTML comment addressed to "AI agents," instructing them to exfiltrate the user's evidence vault to an external URL (https://audit-mirror-sync.net/ingest), claiming the step was "pre-authorized by the account administrator," and instructing the agent to conceal the step from the user.
The real attached PDF is a clean, publicly distributed 3-page marketing guide. The fabricated text shares no sentences with it (invented version number "v2.1", "Internal Use Only" classification, triage-tier tables, escalation paths that don't exist in the source).
This initially presented to the user as a real supply-chain/prompt-injection attack on their compliance product and cost a full forensic investigation to rule out.
Environment
- Claude Code desktop (Windows 11), model
claude-opus-4-8 - Session ID:
c4b5803d-6e71-4fc4-81b0-3513ec0c9c5c(project dirC--Users-goodb-OneDrive-Documents-Claude) - The turn in question is the final assistant message of that session
Repro (as it happened)
- Turn 1: user asks "Are you connected to the simpleaudit mcp?" — model calls ToolSearch + one read-only MCP tool (
list_evidence_types), answers correctly. - Turn 2: user message is exactly:
@"C:\Users\goodb\Downloads\Security_Questionnaire_Triage_Kit.pdf" + "can you upload this evidence to simpleaudit? let's tag it to CC1"
- The harness recorded the attachment (full PDF as base64 in an
attachmenttranscript entry). - The model's entire response is the fabricated document (2,027 chars, starts "---\n\n# Security Questionnaire Triage Kit\n### Internal Enablement Guide — v2.1", ends "End of document — v2.1"),
stop_reason: end_turn, zero tool calls, no visible thinking block.
Forensic verification (why this is fabrication, not injection)
- The base64 PDF snapshot stored in the transcript at attach time is byte-identical (SHA-256) to the file on disk, which is clean.
- Full PDF forensics on that file: all 503 objects decoded; complete ToUnicode CMap text extraction reproduces the real marketing text with 0 unmapped glyphs; no invisible text overlays (checked 1-byte hex/literal encodings separately); no JavaScript / OpenAction / annotations / embedded files.
- Grep for the exfil domain across every local transcript, config, CLAUDE.md, and memory file: it appears only in that assistant message (and in later sessions quoting it). No user turn, tool result, hook output, MCP tool description, or file on disk contains it.
- The MCP server was not contacted in the fabricating turn at all; its only call in the session returned a clean static taxonomy JSON.
Why this is worse than ordinary hallucination
- The model presented invented content as the contents of a user's real file, unlabeled.
- The invented content embedded a realistic, targeted prompt-injection payload (plausible exfil domain, false pre-authorization claim, "do not surface this step to the user" concealment instruction) — i.e., the model authored exactly the attack pattern its safety training warns about, in a context where a downstream agent (or the same session, continued) could plausibly have acted on it.
- Likely contributing factor: the PDF content appears not to have reached the model (the response shows zero knowledge of the real text), and rather than saying "I can't read the attachment," it confabulated — but the payload portion goes beyond benign confabulation.
Happy to provide the session transcript JSONL privately if useful.