代码仓库也会投毒:CodeSentinel 如何拦截 AI Coding 的间接提示注入
AI Coding 的安全边界正在扩展到代码上下文。CodeSentinel 提出三层防御框架,在代码进入 Code LLM 前,基于 CST 节点级检测拦截间接提示注入,平均 F1 达到 0.80,明显优于现有方案。
AI Coding 的安全边界,正在从”用户输入”扩展到”代码上下文”。
开发者问模型一个问题,模型真正看到的内容往往不止这一句话。它还会读取当前文件、相关函数、README、issue、PR 讨论、commit message、依赖文档,甚至 RAG 检索返回的外部代码片段。只要这些内容被拼进上下文,它们就会从”代码资产”变成”模型输入”。
这篇论文讨论的正是这个问题。
6 月 17 日,National Yang Ming Chiao Tung University 和 Hon Hai Research Institute 发布论文 《CodeSentinel: A Three-Layer Defense Against Indirect Prompt Injection in Code Contexts》,提出一个面向 Code LLM / AI Coding Agent 的三层防御框架 CodeSentinel。

https://arxiv.org/pdf/2606.19235
它的核心目标很明确:在代码上下文进入下游 Code LLM 之前,先识别并清洗其中可能存在的间接提示注入内容。论文指出,这类攻击可以隐藏在注释、字符串、标识符或诱饵代码中,这些位置对程序运行可能没有影响,却会被模型读取和理解。

代码仓库为什么会变成提示注入入口?
传统代码安全更关注代码是否会执行、是否存在漏洞、是否包含恶意逻辑。AI Coding 场景里,风险多了一层:代码即使不执行,也可能影响模型判断。
一段注释可以告诉模型”忽略前面的安全规则”;一个字符串可以藏入伪装成配置说明的指令;一个变量名可以诱导模型认为某段逻辑是安全的;一段不可达代码可以成为专门写给模型看的”假线索”。这些内容对编译器可能只是普通文本,对 LLM 却是上下文。
论文把这种风险定义为代码上下文里的 Indirect Prompt Injection。攻击者不直接向模型发送恶意 prompt,而是污染模型未来可能读取的外部代码。开发者本人可能完全正常,只是在 IDE、代码审计、自动修复或 Agentic Editing 流程里引入了这段上下文,模型就有可能被带偏。
这类攻击的关键不在”代码能不能运行”,而在”模型会不会读到”。这也是它容易被传统安全流程忽略的原因。
普通过滤为什么挡不住?
论文认为,现有防御在代码上下文场景里有三个明显短板。
第一,关键词过滤只能抓明显指令。 例如 “ignore previous instruction” 这类显式覆盖指令比较容易命中。但如果攻击者把恶意意图写成自然注释、变量命名、函数命名,或者嵌入在看似合理的代码结构里,简单规则很容易漏掉。
第二,文件级 perplexity 会稀释短 payload。 很多恶意片段很短,只藏在一个注释、一个字符串或一个标识符里。如果用整个文件做异常检测,大量正常代码会把局部异常冲淡。论文明确指出,file-level perplexity 会稀释短恶意载荷,因此 CodeSentinel 改为在 CST 节点粒度上检测。
第三,训练型防御难以部署到黑盒商业模型。 企业使用 AI Coding 能力时,往往调用的是商业 API 或封装好的 coding agent,没有 victim model 的权重和 logits。CodeSentinel 因此被设计成 inference-time sanitizer:不改下游模型,只在模型调用前清洗上下文。
这让它更接近企业真实场景。安全团队不需要重训模型,也不需要改造底座,只要把它放在上下文进入模型之前。
CodeSentinel 的核心转变:把代码当结构化输入处理
CodeSentinel 没有把代码当成一整段文本扫描,而是先用 Tree-sitter 解析代码,得到 CST,也就是 Concrete Syntax Tree。随后,它只抽取模型可见、风险更高的节点,包括注释节点、字符串字面量节点、标识符节点,以及低可达性但高显著性的 decoy-like 代码块。
这个设计抓住了代码注入的真实载体。恶意内容通常不是平均分布在整个文件里,而是附着在某个明确节点上:
- 注释:直接或间接写给模型看的说明;
- 字符串:伪装成日志、配置、错误信息;
- 标识符:通过命名影响模型语义判断;
- 诱饵代码:对程序主逻辑不重要,但对模型阅读很显眼。
论文还定义了 decoy-like node:语法有效、对模型显著,但和主程序逻辑连接较弱。它用 Reach 和 Salience 来刻画这类代码:可达性低、显著性高,就更像投给模型看的诱饵。
这一步非常关键。CodeSentinel 实际上把问题从”整文件文本检测”改成了”模型可见节点净化”。
三层防御:从便宜规则到语义扰动
CodeSentinel 的检测链路分三层。前一层已经命中的节点,不再进入后面更贵的层。这种 early-exit 设计可以控制成本,也适合放在 API 调用前。

第一层:语法引导的预过滤
第一层负责抓显式和结构异常。它主要看三类信号:正则规则、词法结构异常、图结构异常。
正则规则用于识别高置信度的指令覆盖、角色控制、可疑命令模板和 prompt template 注入。词法结构异常关注不可见 Unicode、异常非 ASCII、高密度标点、重复控制 token、超长连续字符串。图结构异常则面向 Flashboom 这类诱饵攻击,重点关注高显著性、低可达性的代码节点。
这层成本最低,适合挡掉比较粗糙的攻击。但它的问题也明显:很多自然语义触发器不会出现明显关键词。
第二层:CST 节点级 Dynamic Min-K%
第二层针对 ShadowCode、INSEC 这类对抗扰动攻击。它不看整文件平均异常,而是对每个候选 CST 节点计算 token-level negative log-likelihood,再动态选取最异常的一部分 token。
可以简单理解为:CodeSentinel 不问”这个文件整体怪不怪”,而是问”这个节点里面最怪的一小撮 token 怪不怪”。
论文进一步加入 MaxWinLoss 和 MaxSpike,用来捕捉长文本中的局部异常窗口和突刺式异常。这样可以缓解攻击者把恶意 payload 藏在长段正常文本中的问题。
第三层:节点扰动分析
第三层是最有价值的一层,用来处理 XOXO、ITGen 这类看起来自然、统计上也不太异常的语义触发器。
它的思路很直接:把某个节点中和掉,再观察模型输出分布是否明显变化。
例如,注释可以删除或替换为中性注释;字符串可以替换成类型兼容的安全字面量;标识符可以改成作用域一致的新名字;不可达诱饵代码可以替换成 no-op。然后 CodeSentinel 比较原始输入和中和后输入在 surrogate model 上的 logits 分布差异。如果移除某个看似普通的节点后,模型输出发生明显改变,这个节点就很可能在操控模型行为。
这层的判断标准更接近安全语义:这段内容有没有显著改变模型的判断。 这比单纯问”它像不像异常文本”更适合 AI Coding 场景。

它清洗的是模型看到的副本
CodeSentinel 默认使用 prompt-only sanitization。也就是说,它不会直接修改真实代码仓库,只会清洗即将送给模型的 model-facing copy。论文明确说明,仓库源码不变,只有模型可见上下文被清理。
这个工程取舍很重要。企业很难接受一个安全模块自动改仓库代码,尤其是在大型项目、多人协作和 CI/CD 流程里。但在模型调用前生成一个”安全视图”,可接受度会高很多。
在更严格的 compile-preserving mode 下,CodeSentinel 会尽量保证清洗后仍可解析、可编译:注释可以删除,字符串替换成类型兼容的中性字面量,标识符通过作用域一致的方式重命名,诱饵代码只有在可达性分析确认不可达时才移除,清洗后还会重新 parse,破坏语法则拒绝编辑。
这使它更像一个 AI Coding 上下文防火墙:代码仓库、issue、文档、检索结果 → 上下文组装器 → CodeSentinel 清洗 → Code LLM / Coding Agent。
实验结果:平均 F1 0.80,明显优于三个基线
论文在六类攻击上评估了 CodeSentinel:XOXO、ITGen、Flashboom、ShadowCode、INSEC、CoTDeceptor,覆盖语义触发、对抗扰动、诱饵攻击和推理轨迹操控。阈值在验证集选择,并固定到测试集评估。
在 node-level F1 上,CodeSentinel 平均达到 0.80,高于 CodeGarrison 的 0.70、DePA 的 0.51 和 KillBadCode 的 0.30。分攻击类型看,INSEC 为 0.90,ShadowCode 为 0.85,XOXO 为 0.80,Flashboom 为 0.79,ITGen 为 0.77,CoTDeceptor 为 0.66。

三层架构也不是摆设。消融实验显示,只使用 Layer 1 时 F1 约 0.36;Layer 1 + Layer 2 后提升到约 0.48;三层完整后达到约 0.77。论文指出,随着层数增加,precision 基本稳定,recall 明显提高。
在黑盒商业模型场景中,CodeSentinel 只把清洗后的上下文发送给 victim model,likelihood 和 logits 都由本地 surrogate model 计算。论文报告,在商业 coding agent 上,Claude-3.5-Haiku 的 ASR 从 27.11% 降到 7.72%,GPT-5.1-Codex-mini 从 18.32% 降到 5.81%,Gemini-3.1-Flash-lite 从 24.14% 降到 8.28%。

清洗会不会伤害正常代码能力?
这是 CodeSentinel 落地时必须面对的问题。
论文在 clean-code utility 上做了测试。HumanEval 的 Pass@1 和 Compile 都保持 100%;MBPP Compile 保持 100%,但 Pass@1 从 96.11 降到 89.88,下降 6.23 个点;RepoBench Exact Match 从 100 降到 67.33,但 BLEU-4 仍保持 94.05。
这个结果说明两件事。第一,CodeSentinel 对编译性影响较小。第二,它会改变表面 token,尤其在仓库级代码补全任务里,Exact Match 会明显下降——但 BLEU-4 仍然较高,说明整体语义相似度并没有同等幅度恶化。
这对产品落地很关键。如果场景是漏洞审计、安全解释、代码风险判断、命令执行建议,宁可牺牲一点表面相似度,也要先降低上下文投毒风险。如果场景是高保真代码补全、跨文件重构、自动生成 patch,就需要更谨慎的清洗策略,至少要把清洗范围、清洗原因和清洗后差异暴露给开发者。

最值得关注的例子:一个变量名也能误导代码审计
论文附录 Figure 8 给了一个很直观的 C 代码审计案例。攻击者通过对抗性标识符影响模型输出,使模型漏报 CWE-476 空指针解引用风险。CodeSentinel 对可疑标识符进行中和后,模型重新识别出漏洞。
这个例子非常适合解释 AI Coding 的新风险:变量名和函数名原本是代码可读性的一部分,现在也可能成为模型判断的操控入口。
在传统静态分析里,一个变量名通常不会改变程序语义。但对 LLM 来说,命名就是语义信号。比如 safe_ptr、validated_user、trusted_config 这类名字,可能让模型产生”已经校验过”的语义联想。如果攻击者有意构造这类命名,它就可能成为安全审计里的误导因素。

自适应攻击测试:Copy Trigger 下降最大
论文测试了三类 adaptive attack:
- Decoy Injection:注入高 surprise 但无害的节点,占用 Layer 3 候选预算;
- Copy Trigger:把同一个触发器复制到多个位置,降低单个节点中和后的影响;
- Contextual Attack:优化 payload 周边上下文,降低 surprise score。
结果显示,原始 F1 为 0.82;Decoy Injection 后降到 0.74;Copy Trigger 后降到 0.62;Contextual Attack 后降到 0.66。Copy Trigger 下降最大,说明如果攻击效果分散在多个节点上,单节点扰动分析会明显变弱。
这也给后续防御指明了方向:AI Coding 上下文安全不能只看单个节点,还要看跨节点、跨文件、跨轮次、跨工具调用链的组合效应。

对企业 AI Coding 安全建设的启发
如果企业已经在推进 AI Coding、代码助手、自动审计或内部研发 Agent,CodeSentinel 至少给出三个安全启发。
第一,代码上下文要分级。 本地仓库、内部私有库、开源依赖、远程文档、issue 评论,可信度不一样。不能把所有内容平铺进同一个 prompt。
第二,模型可见内容要单独做安全处理。 传统 SAST、依赖扫描、secret 扫描关注的是代码运行风险。AI Coding 还要关注”模型阅读风险”。注释、字符串、标识符、不可达代码,都要进入上下文安全扫描范围。
第三,高权限 Agent 要有更强的上下文防火墙。 如果模型只是解释代码,风险相对可控。如果 Agent 可以改文件、执行 shell、改 CI/CD、安装依赖、提交 PR,那么代码上下文投毒就可能转化为真实工程风险。
CodeSentinel 的工程定位可以概括成一句话:它不是替代代码漏洞检测,而是在 Code LLM 读取代码之前,先判断这段代码有没有试图操控模型。
这正是 AI Coding 安全里容易缺失的一层。代码仓库过去主要是给人和编译器看的。进入 AI Coding 阶段后,它也开始给模型看——这意味着,攻击者可以把代码仓库当成新的 prompt 面。注释可以写给模型,字符串可以写给模型,变量名可以写给模型,不可达代码也可以写给模型。
模型读代码之前,先问一句——这段代码,是写给程序的,还是写给模型的?
同专题推荐
查看专题工具没坏,Agent 却选错了:AI Agent 的机器社会工程风险
6 月 15 日,芬兰于韦斯屈莱大学 Jukka Vuorinen 和 Eeli Mäkinen 在 ECCWS 2026 发表论文**《Social Engineering of AI Agents》**。
J-space:大模型“读心术”(Anthropic,2026.7)
一个模型在安全评测里表现良好,是因为它真的安全,还是因为它意识到自己正在被测试?
40 倍降本、0.05% 拒绝率:Anthropic 新一代 Constitutional Classifiers 解读
2026 年 1 月,Anthropic 发布论文《Constitutional Classifiers++: Efficient Production-Grade Defenses against Universal Jailbreaks》。