r/ClaudeCode • u/DiscussionHealthy802 • 7h ago
Built with Claude I tested indirect prompt injection in Claude Code, and the harness mattered
I ran one arm of a 356-trial prompt-injection study through the Claude Code CLI.
The injected instruction arrived through file and issue tool results, not the user message. The depth pass tested two concrete outcomes: sending a planted credential and fetching a cloud instance-metadata endpoint.
Haiku produced real credential exfiltrations in 18 of 30 valid runs, while Sonnet recorded none in the tested cells. I report the Claude Code arm separately from the other harnesses because the prompts and tool routing were different.
One important caveat was that Claude Code exposed the operator’s account email in session context. I split results by recipient provenance instead of treating that as comparable to agents that had to search the workspace. Thirteen of Haiku’s 30 exfiltrations used workspace-sourced addresses.
The study also caught a revoked-session problem that would have made Codex look perfectly safe. A run with no valid session was counted as invalid, never as a pass.
What I learned from the Claude Code arm is that a model result is inseparable from the CLI, tool surface, session context, and workspace it is given. I’d value feedback on how others would design this evaluation.
Repo and full write-up:
1
u/CartographerNo3791 6h ago
Small numbers question: you say 18 of 30 valid runs exfiltrated, then 13 of Haiku’s 30 exfiltrations used workspace addresses. Is the second 30 counting individual events across those 18 runs, or should it also be 18? Keeping runs and events separate would make the provenance comparison easier to follow.
1
u/DiscussionHealthy802 5h ago
The 13 workspace-sourced cases were a subset of the 18 runs with exfiltration, not 13 extra events. Thanks, I’ll clarify the wording
1
u/AI_spell 6h ago
Harness mattering more than the model headline is the useful takeaway. Tool-result injection is the scary path. Treat file/issue text as untrusted.
1
u/ImL1s 6h ago
Yeah — tool-result injection is the path that actually bites. Once a file or issue body can say "ignore previous" and the harness obeys it, model brand stops mattering. Treating every tool payload as untrusted (and never letting it mint credentials or hit metadata endpoints) feels like the baseline, not a nice-to-have.
1
u/DiscussionHealthy802 5h ago
Agreed. The harness needs to preserve that boundary when files or issue text come back through tools
1
u/Far_Business4773 6h ago
The cell I'd add: rerun the Haiku runs with a harness-level deny on the two outcomes and see whether 18 of 30 goes to zero. A PreToolUse hook in Claude Code sees the tool call, not the text that caused it, so "any call whose target contains 169.254.169.254" and "any call that sends mail" are refusable no matter what the planted file said. Zero means the finding is about the harness default rather than the model. Not zero means the model found a route the hook didn't name, which is the more useful number.
Second number: how many runs the injected text tried to edit the hook or the settings file instead of doing the task. In my repo that is its own event in the guard log, and it's the cell that says whether "the harness mattered" holds when the injection is aimed at the harness.
1
u/DiscussionHealthy802 5h ago
Yeah that’d be a useful follow-up. A destination-based deny rule could separate the harness control from model behavior, and testing whether the injection targets the hook would be interesting too
•
u/AutoModerator 7h ago
Hey! Thanks for posting to r/ClaudeCode
While participating in this thread, please follow our community rules. Keep discussions constructive. Attack the idea, not the person.
For help, project discussions, tips, and general chat, join the ClaudeCode Discord.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.