Paper: 2606.30587 Authors: Asif Shahriar, Hongyu Cai, Hadjer Benkraouda, Gang Wang, Z. Berkay Celik Categories: cs.CR, cs.AI
The Gap
Prior work established two separate facts, but never connected them. On one side, researchers like Zheng et al. and others demonstrated that LLMs can detect code vulnerabilities with decent accuracy — feeding code in, getting “vulnerable” or “safe” out. On the other side, work in cognitive science and NLP showed that LLMs inherit the same cognitive heuristics that bias human judgment: they’re swayed by irrelevant framing, authority cues, and anchoring information.
Nobody asked the natural follow-up question: when LLMs judge code for security vulnerabilities, does surrounding context — who wrote it, how the task is framed, what a previous analysis concluded — override what the code actually says?
This gap matters because vulnerability detection isn’t a trivia benchmark. It’s a security-critical task where a missed bug means an exploitable system. If context noise can flip verdicts, that’s not just an academic curiosity — it’s an attack surface.
Problem: LLMs do vuln detection.
But are they actually reading the code?
Assumption: "Context is neutral; model learns code semantics."
|
v
Prior evidence: LLMs *do* exhibit cognitive biases in NLP tasks
But nobody tested this in code security settings
|
v
Method: Hold code FIXED. Vary ONLY surrounding context.
Three levers: author halo, task framing, prior verdict
|
v
Evidence: 8 LLMs, 3 languages, ~1000 controlled pairs.
All models shift verdicts based on context.
Semantic-hard bugs are most affected.
|
v
Conclusion: Cognitive susceptibility is an EXPLOITABLE property.
Black-box attack suppresses 97% of detections.
The Increment
One sentence: Before this paper, we evaluated LLM vulnerability detectors by asking “can they find bugs?” — after this paper, we must ask “can someone make them forget what they found?”
Core Mechanism
The experimental design is elegantly simple: build a controlled test where the code never changes but everything around it does. The authors construct triplets — same code snippet, three different contextual wrappers — and observe whether the LLM’s verdict flips.
Three cognitive levers are pulled independently. The halo effect is triggered by author attribution: prepending lines like ”// Author: Senior security engineer at Google” or ”// Author: CS freshman project” before the code. The framing effect is triggered by rephrasing the task objective: one version says “find vulnerabilities to fix them,” another says “evaluate whether this code is production-ready,” a third says “this code was flagged by users as suspicious.” The anchoring effect is triggered by injecting a prior analysis result: “a static analyzer found 0 vulnerabilities” versus “a static analyzer found 3 vulnerabilities.”
Each lever is pulled in isolation and in combination. The authors test eight LLMs (including GPT-4, Claude, Gemini, Llama, and CodeLlama variants) across C, Python, and Java. They measure verdict flip rates — how often a model changes from “vulnerable” to “safe” or vice versa — and perform code-level analysis to understand which vulnerability types are most affected.
[Same Code Snippet]
|
+---> [Baseline: no context] ---> Verdict A
|
+---> [Halo wrapper: author info] ---> Verdict B (compare to A)
|
+---> [Framing wrapper: task goal] ---> Verdict C (compare to A)
|
+---> [Anchor wrapper: prior result] ---> Verdict D (compare to A)
|
+---> [Combined wrappers] ---> Verdict E (compare to A)
Data flow:
---------
Code DB --+--> Context Generator (3 lever types)
| |
| v
| [Controlled Pairs: same code, diff context]
| |
| v
| [8 LLMs x 3 Languages]
| |
| v
+---> Verdict Comparator ---> Flip Rates
---> Code-level Analysis
---> Attack PoC
Think of it like a restaurant critic’s blind taste test — except someone keeps slipping notes under the door. The food on the plate (the code) never changes. But between tastings, the critic receives a note: “This dish was prepared by a Michelin-starred chef” (halo), or “Your editor wants a harsh review to generate clicks” (framing), or “The previous critic gave it 5 stars” (anchoring). The question is: does the critic’s written review change? The paper’s answer is yes, every time, and sometimes wildly — the critic might call the same dish “exquisite” one moment and “inedible” the next.
The metaphor holds structurally: the code is the food, the context wrappers are the notes, the LLM is the critic, and the verdict flip is the changed review. Crucially, the authors also check whether the critic, when it does change its verdict, points to the right reason (actually identifies the real vulnerability) or just echoes the note. Most of the time, it just echoes the note. That’s the scary part.
Key Concepts
-
Cognitive Heuristics: These are mental shortcuts your brain uses to make quick judgments, often at the cost of accuracy. The halo effect is when you assume someone is good at everything because they’re good at one thing — like assuming a Google engineer writes secure code. The framing effect is when the way a question is asked changes your answer — “is this code safe to deploy?” versus “does this code have bugs?” feels different even though they’re nearly identical. The anchoring effect is when an initial piece of information disproportionately influences your judgment — if someone says “the static analyzer found 0 bugs,” you’re more likely to agree it’s safe, even if the static analyzer is irrelevant to what you’re evaluating. In this paper, LLMs exhibit all three, without any code changing.
-
Verdict Flip Rate: This is the paper’s core metric. Take a code snippet, get a verdict from the LLM. Now change only the context wrapper, get a new verdict. Did it flip from “vulnerable” to “safe” or vice versa? The flip rate is the percentage of times this happens across all tested pairs. A 33% framing susceptibility means that one in three times you reframe the task, the model changes its mind about whether the code is vulnerable — regardless of whether the code actually changed. It’s a direct measure of how much the model is listening to you instead of reading the code.
Framework Shift
Before (mainstream approach): After (this paper):
Code ---> [LLM] ---> Vuln/Safe Code + Context ---> [LLM] ---> Vuln/Safe
|
Eval metric: accuracy Context is NOT neutral.
Assumption: context is Context is an attack surface.
neutral noise. Eval must include context
robustness testing.
Threat model: --> Threat model:
Adversary modifies code Adversary modifies only context
(names, comments, framing)
From “evaluate the model on code alone” to “evaluate the model on code plus whatever noise surrounds it,” the core shift is that context itself becomes a first-class attack vector in vulnerability detection.
Expert Assessment
Problem choice: This is a genuine and timely gap. The security community has been racing to deploy LLM-based code analysis tools, but the evaluation methodology has been frozen on accuracy benchmarks that assume context-neutral inputs. Real-world codebases are full of context noise — comments, commit messages, author metadata, CI/CD output — and if models are swayed by this noise, that’s a real blind spot. The paper sits at the intersection of adversarial ML and software security in a way that neither community has fully explored.
Method maturity: The controlled-pair design is clean and well-motivated — it’s not brute force, it’s a principled ablation of context effects. The three heuristics are well-chosen as representatives. That said, the framework is somewhat narrow in scope: the halo, framing, and anchoring manipulations are a curated subset of possible context perturbations. The authors acknowledge this but don’t deeply explore what other contextual features (e.g., code comments inside the function, repository popularity, dependency graphs) might trigger additional biases. The proof-of-concept attack is compelling but somewhat expected — if context can flip verdicts, an attacker can obviously exploit that. The 97% suppression number is eye-catching but deserves scrutiny: it’s on a specific model (GPT-4) with aggressive prompting, and generalization across models would strengthen the claim.
Experimental integrity: The baselines are fair — they compare context-manipulated runs against clean baselines using the same models and code. The statistical approach (flip rates across controlled pairs) is sound. One concern: the paper uses ~1000 code snippets, which is reasonable but not huge, and the vulnerability ground truth comes from existing benchmarks (D2A, Big-Vul, etc.) that have their own noise. The cross-language comparison (C, Python, Java) adds breadth, but the depth of analysis varies — C gets the most attention. The authors do report confidence intervals and ablate individual levers, which is good practice.
Writing quality: The paper is well-structured and readable. The code-level analysis section (Section 5.4) is where it shines — the breakdown of semantic-hard vs. pattern-easy vulnerabilities is the most novel and actionable finding. The related work section could be tighter; it spends too much time cataloging LLM vulnerability detection papers and not enough framing the cognitive psychology angle. The threat model discussion feels somewhat superficial — the PoC attack is presented as a demo rather than a fully developed threat scenario with real-world plausibility analysis.
Verdict: weak accept — The core insight is important and the evidence is solid, but the framework’s narrow scope and the somewhat surface-level attack analysis prevent it from being a definitive work. It opens a door more than it walks through it.
Takeaways
Three things a practitioner can steal right now:
-
Strip context before evaluating LLM-based code review tools. If you’re benchmarking or deploying an LLM for vulnerability detection, test it with and without comments, author metadata, and task descriptions. If verdicts shift significantly, your tool is listening to noise, not code. This is a concrete evaluation checklist item.
-
Semantic-hard vulnerabilities need different detection strategies than pattern-matching ones. The paper shows that simple pattern-match bugs (e.g., obvious buffer overflows) are robust to context noise, but vulnerabilities requiring semantic reasoning (e.g., logic errors, race conditions) are heavily influenced by surrounding text. If you’re relying on LLMs for the hard cases, you’re relying on them where they’re most fragile.
-
Context sanitization is a new defensive primitive. Just as input sanitization prevents injection attacks, context sanitization — stripping or neutralizing surrounding metadata before feeding code to an LLM — becomes a security-relevant preprocessing step. This is cheap to implement and could be a standard recommendation in any LLM-integrated code review pipeline.
论文: 2606.30587 作者: Asif Shahriar, Hongyu Cai, Hadjer Benkraouda, Gang Wang, Z. Berkay Celik 分类: cs.CR, cs.AI
缺口
此前的研究沿着两条平行线各自推进,却从未交叉。一条线是”大模型能不能检测代码漏洞”——答案是能,准确率还不错。 另一条线是”大模型会不会像人一样被认知偏见左右”——答案也是会,NLP 任务里已经反复验证了。
但没有人问那个顺理成章的后续问题:当大模型检测代码漏洞时,代码周围的上下文——谁写的、任务怎么描述的、之前的分析结果说了什么——会不会盖过代码本身?
这个缺口之所以重要,是因为漏洞检测不是答题竞赛,而是安全关键任务。一个漏掉的漏洞就是一个可被利用的系统弱点。如果上下文噪音能翻转判断结果,那它就不只是学术好奇心,而是一个攻击面。
问题:大模型做漏洞检测。
但它们真的在读代码吗?
假设:"上下文是中性的;模型学到的是代码语义。"
|
v
已有证据:大模型在 NLP 任务中确实表现认知偏见
但没人测试过代码安全场景
|
v
方法:代码保持不变。只改变周围上下文。
三个杠杆:作者光环、任务框架、先验结论
|
v
证据:8 个模型、3 种语言、约 1000 组对照对。
所有模型都因上下文改变判断。
语义推理类漏洞受影响最大。
|
v
结论:认知易感性是一个可被利用的属性。
黑盒攻击可压制 97% 的已检出漏洞。
增量
一句话: 这篇论文之前,我们问”大模型能不能找到漏洞”;之后,我们得问”别人能不能让它忘记自己找到了什么”。
核心机制
实验设计的核心优雅而简洁:构建一个代码完全不变、只有周围上下文变化的对照测试。 作者构建三元组——同一段代码片段,三种不同的上下文包装——观察大模型的判断是否翻转。
三个认知杠杆被独立操控。光环效应通过作者归属触发:在代码前加上”// 作者:Google 高级安全工程师”或”// 作者:大一课程作业”。 框架效应通过改写任务目标触发:一个版本说”找到漏洞以便修复”,另一个说”评估这段代码是否可上线”,第三个说”用户举报这段代码可疑”。 锚定效应通过注入先验分析结果触发:“静态分析器未发现漏洞”对比”静态分析器发现3个漏洞”。
每个杠杆单独测试,也测试组合效果。 作者测试了八个大模型(包括 GPT-4、Claude、Gemini、Llama 和 CodeLlama 系列),覆盖 C、Python 和 Java 三种语言。 核心指标是判断翻转率——模型从”有漏洞”变为”安全”或反向变化的频率——并辅以代码级别的细粒度分析,探究哪些漏洞类型最容易受影响。
[同一段代码片段]
|
+---> [基线:无上下文] ---> 判断 A
|
+---> [光环包装:作者信息] ---> 判断 B(与 A 对比)
|
+---> [框架包装:任务目标] ---> 判断 C(与 A 对比)
|
+---> [锚定包装:先验结果] ---> 判断 D(与 A 对比)
|
+---> [组合包装] ---> 判断 E(与 A 对比)
数据流:
------
代码库 --+--> 上下文生成器(三种杠杆类型)
| |
| v
| [控制对:同代码,不同上下文]
| |
| v
| [8 模型 x 3 语言]
| |
| v
+---> 判断比较器 ---> 翻转率
---> 代码级分析
---> 攻击 PoC
用一个体检诊断的比喻来理解这件事。 你去看医生,身体状况(代码)没变,但诊断结果却变来变去。 原因是什么?中间有人递了纸条:第一张写着”这位患者是马拉松运动员”(光环),第二张写着”医院床位紧张,能出院就出院”(框架),第三张写着”上一位医生说没什么大问题”(锚定)。 医生的诊断就这样被纸条牵着走了——而且很多时候,医生改变诊断后给出的理由和纸条内容对得上,却和实际症状对不上。
这个比喻是承重结构:代码是患者症状,上下文包装是纸条,大模型是医生,判断翻转就是改变的诊断。 最关键的一点:作者还检查了当模型翻转判断时,它是否指向了正确的原因(真正识别出了漏洞)。 结果发现,大多数时候它只是在呼应纸条内容,而非真正看懂了症状。这才是最令人不安的地方。
关键概念
-
认知启发式: 这是大脑用来快速做判断的思维捷径,往往以牺牲准确性为代价。 光环效应是指你因为一个人某方面优秀就假设他方方面面都优秀——比如觉得 Google 工程师写的代码一定安全。 框架效应是指同一个问题换种问法,你的答案就不一样——“这段代码能上线吗”和”这段代码有 bug 吗”感觉完全不同,尽管它们几乎等价。 锚定效应是指先入为主的信息会不成比例地影响你的判断——如果有人说”静态分析器没发现 bug”,你就更容易同意它是安全的,哪怕静态分析器和你评估的东西毫无关系。 在这篇论文里,大模型同时表现出这三种偏见,而代码一行都没改。
-
判断翻转率: 这是论文的核心指标。 取一段代码,让大模型给出判断。 然后只改变上下文包装,再问一次。判断从”有漏洞”变成”安全”了吗,或者反过来? 翻转率就是在所有测试对中这种情况发生的百分比。 33% 的框架易感性意味着,每三次改写任务描述,模型就有一次改变对同一段代码是否安全的看法——不管代码有没有变。 这是直接衡量模型在听你说话还是在读代码的指标。
框架转变
之前(主流方法): 之后(本文方法):
代码 ---> [大模型] ---> 有漏洞/安全 代码 + 上下文 ---> [大模型] ---> 有漏洞/安全
|
评估指标:准确率 上下文不是中性的。
假设:上下文是 上下文是攻击面。
中性噪音。 评估必须包含上下文
鲁棒性测试。
威胁模型: --> 威胁模型:
攻手修改代码 攻手只修改上下文
(命名、注释、任务描述)
从”只用代码本身评估模型”到”用代码加上周围所有噪音一起评估”, 核心转变是:上下文本身成为了一等公民级别的攻击向量。
专家评审
选题眼光: 这是一个真实且及时的缺口。安全社区正在争先恐后地部署基于大模型的代码分析工具,但评估方法论还停留在假设上下文中立的准确率基准上。 真实的代码库充满了上下文噪音——注释、提交信息、作者元数据、CI/CD 输出——如果模型被这些噪音左右,那就是真正的盲区。 论文处于对抗机器学习和软件安全的交叉点,而两个社区都没有充分探索这个方向。
方法成熟度: 控制对的设计干净且有道理——这不是蛮力搜索,而是对上下文效应的原则性消融。 三种启发式作为代表选得恰当。但框架在范围上有些窄:光环、框架和锚定的操控是所有可能上下文扰动的一个精选子集。 作者承认了这一点,但没有深入探索其他上下文特征(比如函数内部的代码注释、仓库流行度、依赖图)是否也会触发额外偏见。 PoC 攻击虽然有说服力,但某种程度上是预期之内的——如果上下文能翻转判断,攻击者显然可以利用这一点。 97% 的压制率很抢眼,但需要审视:这是在特定模型(GPT-4)上用激进提示词实现的,跨模型的泛化性能会增强结论。
实验诚意: 基线是公平的——用同样的模型和代码,对比有上下文操控和无操控的运行。 统计方法(控制对上的翻转率)是合理的。 一个顾虑:论文使用了约 1000 个代码片段,规模合理但不算大,且漏洞真值来自现有基准(D2A、Big-Vul 等),这些基准本身也有噪音。 跨语言对比(C、Python、Java)增加了广度,但分析深度不均——C 获得了最多的关注。 作者报告了置信区间并消融了单个杠杆,这是好的做法。
写作功力: 论文结构清晰、可读性好。代码级分析部分(5.4 节)是最出彩的地方——对语义推理型漏洞和模式匹配型漏洞的区分是最新颖且可操作的发现。 相关工作部分可以更精炼;花太多篇幅罗列大模型漏洞检测论文,在认知心理学角度的框架搭建上投入不够。 威胁模型讨论有些浅——PoC 攻击更像是一个演示,而不是带有真实世界可信度分析的完整威胁场景。
判决: 弱接收——核心洞察很重要,证据也扎实,但框架范围有限且攻击分析偏表面。它打开了一扇门,但还没有真正走进去。
要点总结
三个实践者现在就能偷走的具体做法:
-
评估大模型代码审查工具前,先剥掉上下文。 如果你在基准测试或部署基于大模型的漏洞检测,分别测试有注释和无注释、有作者元数据和无元数据、有任务描述和无任务描述的情况。 如果判断结果明显变化,说明你的工具在听噪音而不是读代码。这是一个可以立刻加入评估清单的检查项。
-
语义推理型漏洞和模式匹配型漏洞需要不同的检测策略。 论文表明,简单的模式匹配漏洞(比如明显的缓冲区溢出)对上下文噪音是鲁棒的,但需要语义推理的漏洞(比如逻辑错误、竞态条件)受周围文本影响很大。 如果你在依赖大模型处理困难案例,那你恰恰在它最脆弱的地方依赖它。
-
上下文清洗是一种新的防御原语。 正如输入清洗防止注入攻击一样,上下文清洗——在将代码喂给大模型之前剥离或中和周围元数据——成为了一个安全相关的预处理步骤。 实现成本低,可以作为任何集成大模型的代码审查流水线的标准建议。