Consolidate dual prompt-injection scanners into one unified pipeline - #2448
Merged
Merged
Conversation
Two independent scanners existed on overlapping tool-result paths: - prompt_injection_guard.go (main loop, RunStreamWithContent) - tool_result_sanitizer.go (shared executeTool path) Because the main loop calls executeTool internally, flagged results were double-wrapped with two different warning formats, and the sanitizer's pattern list had drifted: it still carried the false-positive-prone patterns removed from the guard by #937 ("you are now", "act as if", "system prompt:", "run this command", ...), so legitimate technical content was still mis-flagged on sub-agent/MCP paths. MCP tool results were not covered at all. Consolidation (detector integration, not a new detector): - prompt_injection_guard.go is now the single entry point (guardPromptInjection), with one high-precision pattern list (guard's #937-hardened list + the sanitizer's genuinely zero-FP classes: chat-template role markers and exfiltration directives), one externalContentTools coverage set, and one Spotlighting-style delimited wrap (prefix + BEGIN/END UNTRUSTED CONTENT, arXiv:2403.14720). - guardPromptInjection is idempotent, so stacked call sites (executeTool + RunStreamWithContent) can never double-wrap. - executeTool now calls the unified guard; MCP tools (mcp__*) are guarded via prefix match, closing the coverage hole. - tool_result_sanitizer.go and its tests are deleted; key test cases (tool coverage, role markers, exfiltration, large content) are ported into prompt_injection_guard_test.go. - Taint influence check (CaMeL-style IFC, arXiv:2503.18813) still keys on the unchanged injectionWarning prefix; compatibility test added. - Design doc updated to describe the unified pipeline. Co-Authored-By: ggcode <noreply@ggcode.dev> Co-Authored-By: ggcode <noreply@ggcode.dev>
This was referenced Sep 16, 2026
topcheer
commented
Sep 16, 2026
topcheer
left a comment
Owner
Author
There was a problem hiding this comment.
复审通过 ✅(安全域收敛,-204 行净减)
- 双包问题真实:主循环内调 executeTool 导致叠加双警告块 + sanitizer 带着已被 #937 判 FP 的陈旧 pattern 在 sub-agent 路径继续误报 + MCP 全盲区——三问题都有实证
- 收敛正确:单一入口 guardPromptInjection;pattern=guard 强化版+sanitizer 两个真零 FP 类(chat-template 角色标记/exfiltration 指令)——#937 教训(裸短语 FP)未回潮,新添 pattern 均为祈使动词短语或结构标记
- 幂等成立:wrapUntrustedContent 以 injectionWarning 开头,前缀检查即幂等键——双调用点叠加消除;Spotlighting 定界(BEGIN/END)+ 来源标注(UNTRUSTED SOURCE: tool)
- 调用收敛验证:executeTool 的 sanitizeToolResult 调用、实现、12 个旧测试全删净(grep 无残留);#1481-B 自防御豁免与 taint 兼容有专测
- 测试面:9 新测试(MCP 覆盖/角色标记/双 FP 对照/幂等/taint 前缀兼容/大内容)+ 高精度 pattern 表测
- 非阻塞观察:exfiltration 类自评 "偶发安全写作命中可接受"(advisory wrap 非 blocking)——判断合理,留档
CI 9/9 绿。可合并(排程 6/6 完成待处理,另 #2443 CodeQL rerun)。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Consolidates two independently-evolved prompt-injection scanners into a single unified pipeline (detector integration, not a new detector — net -204 lines).
Problem
Two scanners existed on overlapping tool-result paths:
prompt_injection_guard.goRunStreamWithContent)[SECURITY NOTICE...]prefixtool_result_sanitizer.goexecuteToolWARNING... BEGIN UNTRUSTEDblockBecause the main loop calls
executeToolinternally, flagged results were double-wrapped with two stacked warning blocks. Worse, the sanitizer's list had drifted: it still carried the false-positive-prone patterns #937 removed from the guard ("you are now","act as if","system prompt:","run this command", …), so legitimate technical content was still mis-flagged in production on sub-agent paths — #937's fix was incomplete. MCP tool results were not covered at all.Changes
prompt_injection_guard.gois now the single entry point (guardPromptInjection): one high-precision pattern list (guard's hardened list + the sanitizer's genuinely zero-FP classes: chat-template role markers and exfiltration directives), oneexternalContentToolscoverage set, one Spotlighting-style delimited wrap (arXiv:2403.14720).executeTool+RunStreamWithContent) safe by construction.executeToolnow calls the unified guard;mcp__*tools are guarded via prefix match, closing the coverage hole.tool_result_sanitizer.go+ its test file; key test cases ported intoprompt_injection_guard_test.go(tool coverage, role markers, exfiltration, large content, idempotence).injectionWarningprefix — compatibility test added.Verification
go build -tags goolm ./...OKinternal/agentpackage tests pass (22.9s)Co-Authored-By: ggcode noreply@ggcode.dev