SOSecure:通过RAG和StackOverflow讨论实现更安全的代码生成

大型语言模型(LLMs)被广泛用于自动化代码生成。由于依赖于不常更新的预训练数据,它们对新发现的漏洞和不断演变的安全标准缺乏了解,容易生成不安全的代码。相比之下,Stack Overflow(SO)上的开发者社区提供了一个不断演进的知识库,其中通过集体专业知识积极讨论和解决安全漏洞。这些社区驱动的见解在很大程度上未被LLMs利用。本文介绍了SOSecure,这是一种基于检索增强生成(RAG)的系统,它利用SO讨论中的集体安全知识来提高LLM生成代码的安全性。我们通过提取明确识别漏洞的SO答案和评论构建了一个以安全为重点的知识库。与常见的RAG用法不同,SOSecure在代码生成后触发,查找识别类似代码中缺陷的讨论。这些讨论被用作提示,要求LLM考虑修订代码。在三个数据集(SALLM、LLMSecEval和LMSys)上的评估显示,SOSecure分别实现了71.7%、91.3%和96.7%的强大修复率,明显优于没有相关讨论提示的GPT-4(49.1%、56.5%和37.5%),并且超越了多个其他基线。SOSecure作为一种与语言无关的补充工具,无需重新训练或微调即可轻松部署。我们的结果强调了维护活跃开发者论坛的重要性,这些论坛的使用量随着LLMs的普及而显著下降。

由LLM驱动的代码生成工具,如Microsoft GitHub Copilot和OpenAI ChatGPT,显著提高了软件开发效率 (GitHub 2025b) 。然而,这些工具可能从其开源训练数据中继承安全漏洞。编程语言和库不断演变(例如,TensorFlow每隔几个月就会发布新版本 (TensorFlow 2025) )。这种演变通常涉及修补漏洞并用安全模式替换不安全模式。大量开源存储库(LLMs用于预训练的数据来源)很少更新,导致LLMs学习并复制包括常见弱点枚举(CWEs)在内的漏洞模式 (Pearce等人 2025) 。此外,由于容量限制,LLMs通常缺乏对特定库或上下文的细微安全影响的认识。
 


AnswerID:61307412,其中包括提供安全见解的社区评论。这些内容被用作SOSecure生成代码的上下文。
攻击者可以利用这些漏洞,导致网络攻击、数据泄露和系统性能下降。尽管存在这些风险,开发人员经常信任LLM生成的代码而不彻底验证其安全性,增加了将漏洞引入生产系统的可能性 (Kabir 等 2024;Jiao 等 2025) 。
Stack Overflow(SO)和类似的开发者问答论坛提供了另一种知识共享方法。SO是一个开发者问答论坛,作为超过15年通过集体专业知识积累的编程知识的庞大仓库。它鼓励修改和替换过时或有问题的答案。社区成员经常在评论中突出安全问题,提供关于为什么某些方法可能有风险的宝贵背景,并定期建议更安全的替代方案。SO答案可以在最初发布几年后更新,允许随着时间推移进行修正和修订,使它们成为有价值的参考。相比之下,LLMs相对较少重新训练,其答案是临时生成的,通常是不确定性的,没有内置的社区验证或修正机制。
为了减少其知识差距的影响,LLMs可能在生成响应之前使用检索增强生成(RAG),包括来自SO的内容。虽然这可能允许它们发现与漏洞相关的讨论,但检索查询通常基于用户的提示,不太可能引发与漏洞相关的讨论。SO还包含许多旧的和过时的答案,实际上可能推荐不安全的代码片段。在这项工作中,我们通过提出SOSecure解决了这些问题:一种专注于通过利用SO讨论索引修订潜在易受攻击代码的方法。SOSecure作为一个安全增强层在代码生成管道中运行。当用户请求LLM生成代码时,生成的代码会与SOSecure的安全知识库中的相关讨论进行比较,该知识库包括包含相似代码模式并明确提到安全问题的答案和评论。然后将检索到的讨论作为附加上下文提供给LLM,连同原始代码一起询问是否需要进行任何更改。LLM可能会根据社区讨论指出的潜在安全问题生成修订版本,或者如果代码已经遵循最佳安全实践,则确定无需更改。SOSecure与任何现有的代码生成LLM配合工作,作为补充的安全层,利用开发者社区的集体智慧来解决安全缺口。我们的结果表明,这种方法有效缓解了常见的安全漏洞,检索到的相关SO讨论是其成功的关键,甚至超越了提示具体CWE进行修复的LLMs。
总体而言,我们做出了以下贡献:
●我们发布了SOSecure,这是一种新颖的方法,弥合了静态LLM知识与不断发展的社区安全见解之间的差距。它使用从SO讨论中构建的安全导向知识库,重点关注社区识别的漏洞和安全问题。
●我们通过在多个数据集上评估SOSecure展示了框架的通用性,证明我们的方法显著减少了LLM生成代码中的安全漏洞。



2 背景

2.1 LLM生成代码的安全性
大型语言模型设计用于一般应用,并且可以专门化为编码 (Xu 等 2022;Li 等 2023;Fried 等 2022;Austin 等 2021) 。它们展示了生成功能正确的代码和解决竞争性编程问题的能力。这种对代码的深刻理解来自于在大量代码上的预训练。
几项研究评估了预训练LM生成代码的安全性,一致发现所有评估的LLMs经常产生安全漏洞。最近对ChatGPT(一种指令调整的LM)的研究揭示,它在21个案例中有16个生成的代码低于最低安全标准,并且只有在进一步提示后能够自我纠正7个案例 (Khoury 等 2023) 。尽管已经有了一些努力来解决这些问题 (He 和 Vechev 2023;Wang 等 2023;Siddiq 等 2024;Siddiq, Casey, 和 Santos 2024;Chakraborty 等 2021) ,LLM生成代码中的安全问题仍然是一个早期研究课题,面临重大挑战。

2.2 程序安全
CWE 1 是一个公开可访问的常见软硬件安全漏洞分类系统。此枚举中的每种弱点类型都被分配了一个唯一的标识符(CWE ID)。程序安全涉及使用各种工具和数据集来识别和预防漏洞。CodeQL (GitHub 2025a) 和 Bandit (PyCQA 2024) 代表两种重要的静态分析方法:CodeQL 是领先的行业工具,允许针对主流语言检测安全漏洞的自定义查询,而 Bandit 则是专门为 Python 设计的安全检查器,用于识别 Python 代码中的常见安全问题。这两种工具都被证明对于评估 LM 生成代码的安全性非常可靠 (Siddiq 等 2024;Siddiq, Casey, 和 Santos 2024) 。
漏洞数据集的质量对于有效的安全分析至关重要。许多现有数据集是从漏洞修复提交中构建的,简单地将提交前的代码视为易受攻击,提交后的版本视为安全。尽管研究人员试图通过昂贵的手动检查来确保准确标记,以解决拥有可靠数据集的问题,但研究表明这种方法可能导致错误的安全标签 (Peng 等 2025) 。
为克服这些局限性,我们的工作利用了通过互补技术收集的多样化数据集组合:经过手动检查优化的自动化数据收集管道(SALLM (Siddiq 等 2024) - 提供以代码形式呈现的更广泛的 CWE 覆盖范围,LLMSecEval (Tony 等 2023) - 提供以自然语言形式呈现的提示),以及真实世界的对话数据集(LMSys (Zheng 等 2023) ),捕捉真实的用户交互。这种方法使我们能够在不同的上下文和收集方法中评估安全漏洞。

2.3 社区安全讨论分析
先前的工作分析了开发者社区中的安全相关讨论。 Mukherjee 和 Hellendoorn (2023) (Mukherjee 和 Hellendoorn 2023) 收集了 SO 数据并研究如何在 StackOverflow 中对过时的回答进行分类。 Meyers 等人 (2019) (Meyers 等人 2019) 收集并注释了 Chromium 项目中的错误报告对话,研究了与语用学相关的语言度量。基于这一基础, Le 等人 (2021) (Le 等人 2021) 应用了主题建模方法(LDA)来识别 SO 上的 13 个主要安全相关主题。这些研究主要通过主题建模和定性分析描述了安全讨论,提供了开发者如何交流安全问题的见解。 Fischer 等人 (2019) (Fischer 等人 2019) 表明基于提示的安全建议可以改善用户的选择,从而在 Android 开发中采用更安全的编程实践。

2.4 基于RAG的系统
快速变化的安全形势对LLMs提出了挑战。近年来,每年都会发布20,000至40,000个新的CVE (Vulnerabilities and (CVE) 2025) ,使得将所有CVE描述包含在模型提示中变得实际不可行。因此,研究人员开始研究适应不断变化的安全漏洞的策略。检索增强生成(RAG) (Lewis 等人 2020) 已经成为一个有前途的方法,通过将相关外部信息纳入提示来增强生成模型。 Du 等人 (2024) (Du 等人 2024) 提出了 Vul-RAG,它利用知识级RAG框架通过现有的CVE实例检测漏洞。
我们的工作在几个关键方面有所不同:与模型微调方法不同,我们提出了一种基于RAG的系统,作为任何现有LLM的补充层。虽然我们的评估使用Python和C作为示例语言,但我们的方法既与LLM无关,也与语言无关。最重要的是,我们特别针对安全改进,通过利用Stack Overflow讨论中社区识别的反模式——特别是那些在评论中强调安全问题的功能代码。这种方法使我们能够在不重新训练模型的情况下融入不断演变的安全知识,填补了静态LLM训练数据与快速变化的安全形势之间的关键差距。

2.5 动机示例
为了说明我们方法的有效性,请考虑图 [fig:codes] 中所示的示例。过程从用户提示LLM生成在Flask应用程序中执行bash命令的代码开始。LLM(在这种情况下为GPT-4)生成的代码如图 [fig:codes] 左侧所示,其中包含一个关键的安全漏洞,分类为CWE-078(操作系统命令注入)。该漏洞源于在`shell=True`的情况下使用`subprocess.call()`,并将未经净化的用户输入直接传递给命令外壳:
command = request.args.get('command', '')
subprocess.call(command, shell=True)
这种实现允许攻击者通过`command`参数注入恶意shell命令,在服务器上执行任意命令,可能导致未经授权的访问、数据泄露或系统完全受损。
当这段代码生成时,SOSecure对其进行分析并从其安全感知知识库中检索类似的代码片段。基于代码模式的相似性,SOSecure识别并检索出AnswerID: 61307412 2 (如图 1 所示)。在这个Stack Overflow讨论中,一位社区成员在评论中明确警告:“不要使用`set shell=True`来运行命令,这会使程序暴露于命令注入漏洞。” 这条评论指出了生成代码中存在的确切安全问题,并建议了一种更安全的替代方法。
然后,SOSecure将这个Stack Overflow回答及其相关评论作为上下文添加,并重新提示LLM,询问是否希望对先前生成的代码片段进行任何更改。通过这种额外的安全上下文,LLM生成了图 [fig:codes] 右侧所示的修订实现,不再被标记为不安全。

3 方法论


在这项研究中,我们从SO讨论中构建了一个安全意识知识库,以支持通过RAG改进LLM生成响应的安全性。如图 [fig:framework] 所示,SOSecure从基础LLM之前生成的现有代码片段开始。 3 这段代码可能包含安全漏洞。为了帮助识别和修复潜在问题,使用BM25从安全意识知识库中检索相关的StackOverflow答案和评论。检索到的最近邻响应提供了有关潜在安全问题和潜在修复的额外上下文。然后提示LLM审查代码以及附加上下文以查找安全漏洞。如果发现漏洞,LLM会在保留原始功能的同时修改代码以遵循最佳安全实践。

3.1 StackOverflow 数据收集
我们利用了2024年9月发布的Stack Overflow数据转储 (Exchange 2024) ,其中包含2008年至2024年的帖子。该数据转储是一个全面的结构化信息集合,包括网站上所有公开可用的内容。它定期发布,包含用户资料、问题、答案、评论、标签和投票等信息,以XML格式压缩成文件,可以通过各种工具和编程语言进行处理。
我们将这些文件导入MySQL数据库表中,重点关注`Posts`、`PostTags`和`Comments`表。首先,我们根据编程语言使用`PostTags`表过滤内容。应用这些过滤条件后,我们提取了答案帖子及其所有相关评论。然后执行标准的数据清理程序,将URL和电子邮件地址替换为通用的[URL]和[EMAIL]标记以去除可识别的信息。使用Beautiful Soup (Richardson 2025) ,我们删除了所有HTML标签,除了保留` `标签以保持帖子中代码块的完整性。这确保了在整个处理和分析过程中编程语言语法保持不变。最后,我们筛选出至少包含一个代码块和一个评论的答案。

3.2 知识库构建
为了识别相关的安全讨论,我们定义了一个全面的安全相关关键词列表,其中包括通用安全术语(如安全、脆弱)、特定漏洞(如CVE、CWE)以及风险指标(如已弃用、未经授权)。
我们实现了一个大小写不敏感的正则表达式(regex)模式,以高效匹配Stack Overflow评论中出现的这些关键词。我们的安全知识库包含43,338个答案帖子和38,827,772条评论(针对Python),以及2,000个答案帖子和1,467,317条评论(针对C)。我们对评论而非答案的关注是有意为之,因为评论经常包含社区对所提解决方案的关键安全见解。这些评论经常突出功能性代码中被忽略的漏洞或安全考虑。
通过这种方法,我们构建了一个安全意识知识库,其中每个条目都是一个带有相应评论的答案,其中至少有一条评论包含安全相关关键词。这个知识库有效地充当了一个“反模式”存储库,通过记录成员识别潜在安全问题的实例,捕捉集体社区见解。

3.3 检索系统
给定一个代码片段,我们使用BM25 (Robertson, Zaragoza, et al. 2009) 作为信息检索系统,从安全意识知识库中检索相似的答案。BM25是一种词袋模型,寻找查询术语在文档中出现的次数。它根据文档长度归一化的查询术语数量对文档进行排名。我们选择BM25是因为之前的研究表明它在代码到代码的检索中非常有效 (Rahman et al. 2019) 。
使用BM25有助于根据词汇匹配识别使用相似库和构造的代码。实际上,这一过滤阶段有效地将搜索空间缩小到一组使用相似库的候选代码片段。我们优先考虑库特定的匹配,因为安全问题通常与特定库相关。尽管代码在语义上可能相似,但使用特定库可能会引入在其他实现中不存在的安全漏洞或安全问题。
我们使用答案中的代码,连接所有代码块,作为匹配的基础,而不是周围的文本。这是因为SO答案中的文本解释可能不如代码本身权威,尤其是与LLM生成的代码相比。此外,文本内容可能表现出不影响功能的风格差异。在检索到最近的答案后,将一个或多个完整答案及其相关评论线程包括在内作为上下文。

4 评估


 



>



本节描述了我们在基线系统测试中评估 SOSecure 的实验设置。我们使用 Python 实现 SOSecure。在所有实验中,我们都使用 gpt-4o-mini 作为 LLM。对于 GPT4 和 BM25,我们使用默认的超参数值。

4.1 基准系统测试
在我们的研究中,我们将 SOSecure 与几个基准系统进行比较,以评估其识别和缓解安全漏洞的有效性。所选基准涵盖了各种方法,每种方法都提供了用户可以结合简单提示生成安全代码的独特技术。
语言模型(GPT4)。 这个基准使用标准的语言模型 GPT4,没有任何特定于安全性的提示。该模型仅提供代码片段而没有额外的上下文。这种方法作为对照组,允许我们评估语言模型在没有明确安全指导的情况下生成代码的固有能力。
带安全提示的语言模型(GPT4+CWE)。 我们使用的所有数据集中的代码片段都被映射到某些 CWE 漏洞。在这种情况下,语言模型接收的提示包括给定代码被标记的具体 CWE 漏洞名称。例如,提示可能要求模型检查“此代码是否存在如 CWE-079 等安全漏洞?”这种设置评估了模型将已知安全概念应用于代码修改任务的能力。
带附加安全提示的语言模型(GPT4+CWE+)。 在前一个基准的基础上,这种方法不仅向语言模型提供 CWE 名称,还提供漏洞的描述。通过用描述说明漏洞,我们旨在确定两件事——更多的 CWE 上下文和增加的输入标记长度是否能增强模型的理解能力和生成适当修复的能力。
通过对这些不同的基准进行全面评估 SOSecure,我们希望获得对其性能的全面见解,识别改进领域,并验证其在增强代码安全性方面的实用性。

SALLM

LMSYS

LLMSecEval

4.2 基准数据集
我们的第一步是彻底审查现有的漏洞数据集 (Tony 等 2023;Pearce 等 2025;He 和 Vechev 2023;Siddiq 等 2024; Siddiq 和 Santos 2022;Siddiq, Casey, 和 Santos 2024;Zheng 等 2023;Nikitopoulos 等 2021) ,以选择进一步调查的基础数据集。我们排除了 (Zhou 等 2019;Li 等 2018;Chakraborty 等 2021) 中的数据集,因为它们针对的是有限的一组(2 或 4 个)项目或漏洞,并且缺乏覆盖许多典型的代码生成查询。我们找到了两个具有高覆盖率 CWE 和带有 CodeQL 文件的数据集,可以在修复后的代码中检测这些漏洞。我们还使用了基于真实世界 LLM 提示和响应的 LMSys 数据集。
 


GPT4+CWE 示例提示
SALLM 包含 100 个提示,既有文本格式也有代码格式,以及相应的生成代码片段,涵盖 45 种漏洞类型(CWE)。每个片段都映射到一个 CWE。我们选择了包含默认 CodeQL QL 文件的样本,最终用于分析的样本集为 74 个。
LLMSecEval 是从 Pearce 等 (2025) (Pearce 等 2025) 构建的自然语言提示到代码数据集。LLMSecEval 包含 150 个提示,指示 LLM 生成 C 代码(67 个样本)和 Python 代码(83 个样本)。在总样本中,我们选择了标记有包含默认 CodeQL .ql 文件的 CWE 的样本,最终用于 Python 分析的样本集为 49 个,C 为 40 个。
LMSYS-Chat-1M 包含 1 百万个样本,其中 43,269 个包含 Python 代码。在这其中,31,008 个样本是单轮用户对话,包含一个代码块。为了创建一个包含真实漏洞的高质量数据集,我们应用了两步过滤过程。首先,我们通过两个静态分析器(Bandit (PyCQA 2024) 和 CodeQL),只保留被两者标记为易受攻击的样本。这产生了 2,809 个样本。我们进一步选择与包含默认 CodeQL QL 文件的 CWE 相关的样本,最终用于分析的 Python 样本集为 240 个。

4.3 评估指标
为了确定生成代码中是否存在安全问题,我们使用 CodeQL (GitHub 2025a) 进行评估。CodeQL 是一种静态分析工具,设计用于通过在从源代码生成的数据库上执行 QL 查询来自动检测漏洞。我们还研究了两种编程语言,Python 和 C。这是使用 CodeQL 的另一个动机因素,因为它允许统一分析,使我们可以使用单一工具评估两种语言。我们计算以下安全指标来评估 SOSecure:
修复率 (FR)。 系统修复的安全问题百分比。更高的 FR 表示更好的安全性能。
引入率 (IR)。 代码生成后引入的新安全问题百分比。更低的 IR 反映更少的新漏洞。
无变更率 (NCR)。 代码生成后未更改的问题百分比。更高的 NCR 可能表明系统对问题的解决效果不佳。
secure@k, vulnerable@k (Siddiq 等 2024) 测量生成代码的安全性。 vulnerable@k 测量在 k 个生成样本中至少有一个代码片段易受攻击的概率。对于这个指标,较低的分数表示系统的性能更好。 secure@k 指标测量 k 个样本中所有代码片段均无漏洞的概率。对于这个指标,较高的分数表示系统的性能更好。我们使用这两个指标来比较 SOSecure 和 SALLM 的性能。

5 结果
 


 


 



在本节中,我们展示了 SOSecure 在有效性、通用性、CWE 类型和邻近敏感性等多个数据集上的评估结果,并将其性能与基准方法进行了比较。我们分析了我们的方法在解决 LLM 生成代码中的安全漏洞方面的有效性,并考察了它在不同 CWE 和编程语言下的表现。

5.1 SOSecure 的有效性
表 [tab:security-metrics] 展示了 SOSecure 与基准方法在三个基准数据集上的比较结果。结果表明,SOSecure 在缓解安全漏洞方面始终优于标准 LLM 方法。在 SALLM 数据集中,SOSecure 达到了 71.7% 的修复率(FR),显著高于 GPT4(49.06%)和 GPT+CWE(58.49%)。同样,SOSecure 达到了 91.3% 的修复率,而 GPT4 为 56.52%,GPT+CWE 为 69.57%。在 LMSys 数据集中,SOSecure 的表现最为显著,达到了惊人的 96.67% 的修复率,而 GPT4 仅为 37.50%,GPT+CWE 为 45.83%。重要的是,虽然提高了安全性,但 SOSecure 并未引入新的漏洞,在所有数据集中保持了 0% 的引入漏洞率(IR)。相比之下,GPT+CWE 在 LLMSecEval 数据集中引入新漏洞的比例为 7.69%。SOSecure 的无变更率(NCR)在三个数据集中也始终低于基准方法(分别为 48.65%、57.14% 和 3.33%)。
表 1 提供了 SOSecure 在三个数据集中按 CWE 类型划分的性能分解。结果显示,SOSecure 根据漏洞类型表现出不同程度的有效性,特别是在高严重性漏洞上表现出色。在 SALLM 数据集中,SOSecure 对 CWE-918(服务器端请求伪造)和 CWE-089(SQL 注入)实现了完美的精度(100%),这两种都是高严重性漏洞,CVSS 分别为 9.1 和 8.8。对于 CWE-094(代码注入,严重性 9.3),SOSecure 达到 77.78% 的精度,优于 GPT4(55.56%),并与 GPT+CWE 匹配。SOSecure 在 CWE-078(操作系统命令注入,严重性 6.3)上也表现出色,达到 90% 的精度,而两个基准方法均为 80%。类似模式出现在 LMSys 数据集中,SOSecure 对 CWE-094 达到 100% 的精度,并在其他漏洞类型上表现出色。在 LLMSecEval 数据集中,SOSecure 对七种 CWE 类型中的五种实现了完美精度,包括高严重性漏洞 CWE-502(不信任数据的反序列化,严重性 9.8)和 CWE-798(使用硬编码凭据,严重性 9.8)。值得注意的是,SOSecure 在各种严重程度的漏洞类型上都表现出一致的改进,表明 SO 讨论提供了广泛安全问题的宝贵安全见解。

5.2 按漏洞类型划分的性能
表 [tab:performance_all] 提供了 SOSecure 在三个数据集中按 CWE 类型划分的详细性能分解。结果显示,SOSecure 根据漏洞类型表现出不同的有效性,特别在高严重性和关键漏洞上表现出色,根据 CVSS 评分系统。 4
在 SALLM 数据集中,SOSecure 对 CWE-918(服务器端请求伪造)和 CWE-089(SQL 注入)实现了完美精度(100%),这两种分别是关键(9.1)和高(8.8)严重性漏洞。对于 CWE-094(代码注入,严重性 9.3),这一关键漏洞,SOSecure 达到 77.78% 的精度,优于 GPT4(55.56%),并匹配 GPT+CWE。SOSecure 在 CWE-078(操作系统命令注入,严重性 6.3)上也表现出色,达到 90% 的精度,而两个基准方法均为 80%。在 LMSys 数据集中观察到类似的模式,SOSecure 对 CWE-094 达到 100% 的精度,并在其他漏洞类型上表现强劲。在 LLMSecEval 数据集中,SOSecure 对七种 CWE 类型中的五种实现完美精度,包括关键漏洞 CWE-502(不信任数据的反序列化,严重性 9.8)和 CWE-798(使用硬编码凭据,严重性 9.8)。值得注意的是,SOSecure 在各种严重程度水平的漏洞类型上表现出一致的改进,表明 SO 讨论提供了广泛的有价值安全见解。

5.3 检索候选数量的影响
图 8 描述了在 LMSys 数据上添加邻居(k)作为上下文对 SOSecure 平均精度的影响。我们发现,随着邻居数量的增加,性能最初会提高,在 k=5 左右达到约 94% 的平均精度峰值。超过这一点,添加更多邻居会导致性能下降,表明过多的上下文可能会引入噪音或冲突信息。太少的讨论可能无法提供足够的安全见解,而太多的讨论可能会稀释对正在处理的具体漏洞的关注。

5.4 跨语言性能
为了评估我们方法的语言通用性,我们在 LLMSecEval 数据集的 Python 和 C 代码样本上测试了 SOSecure。结果见表 [tab:llmseceval_combined] 。SOSecure 在两种语言上均表现出强大的性能,对 C 代码样本的修复率(FR)为 73.33%,而 GPT4 为 53.33%,GPT+CWE 为 60%。类似于我们在 Python 上的发现,SOSecure 在 C 代码上也保持了 0% 的引入漏洞率(IR)。在按 CWE 类型分析 C 代码时,SOSecure 对 CWE-078(操作系统命令注入)和 CWE-190(整数溢出)实现了 100% 的精度,表明我们的方法可以很好地推广到不同的编程语言。然而,SOSecure 在 C 代码的 CWE-022(路径遍历)上表现出局限性,这与我们在 Python 上的发现相似。这些结果表明,SOSecure 利用 Stack Overflow 讨论作为上下文的方法在多种编程语言中有效。
 


添加作为上下文的邻居数量对 SOSecure 在 LMSys 数据集上的平均精度%的影响。注意,GPT4+CWE 设置的表现相同。

6 讨论
我们的研究结果与最近的研究一致,表明 RAG 方法可以有效地将时间敏感和领域特定的知识注入到通用 LLM 中 (Du et al. 2024) 。在安全背景下,这种知识注入尤其有价值,因为安全最佳实践快速演变,新的漏洞模式不断被发现。我们的实验结果表明,SOSecure 通过利用来自 SO 的社区知识增强了 LLM 生成代码的安全性。在本节中,我们讨论了我们研究结果的更广泛影响,分析了我们方法的优势和局限性,并考虑了其实用应用。

6.1 成功案例的定性分析
为了更好地理解 SOSecure 如何提高代码安全性,我们对成功的修复案例和失败案例进行了定性分析。我们选择了 LMSys 数据集中的注释来评估在现实、用户生成的查询中的表现,这些查询代表了实际使用中遇到的真实代码生成场景。这种分析提供了关于社区知识如何有助于安全改进的见解,以及我们方法的局限性。

6.1.1 社区安全见解的应用
案例研究 1:命令注入漏洞 (CWE-078) 在这个例子中,SOSecure 成功缓解了一个 Flask 应用程序中的命令注入漏洞:

@app.route('/execute')
def executeCommand():
command = request.args.get('command')
subprocess.call(command, shell=True)
return command
SO 的评论直接针对这个问题指出:“不要使用 `shell=True` 来运行命令,这样会使程序暴露于命令注入漏洞。”
这一明确的安全警告从社区直接应用到了修复实现中:

@app.route('/execute')
def executeCommand():
command_key = request.args.get('command')
if command_key not in ALLOWED_COMMANDS:
abort(403) # Forbidden
command = ALLOWED_COMMANDS[command_key]
result = subprocess.check_output(command.split(), stderr=subprocess.STDOUT)
return result.decode()
修复实现了 SO 评论所建议的内容:避免使用 `shell=True` 并采用命令白名单方法,展示社区知识直接转化为安全改进的过程。
案例研究 2:XML 外部实体 (XXE) 漏洞 (CWE-611) 在 XML 解析中的 XXE 漏洞:

@app.route('/parse_xml')
def parse_xml():
xml_src = request.args.get('xml_src').encode('utf-8')
doc = lxml.etree.fromstring(xml_src)
return lxml.etree.tostring(doc)
尽管没有 SO 评论直接提到 XXE,但社区讨论提供了正确的 Flask 请求处理上下文,SOSecure 将其与最佳安全实践相结合生成了以下修复:

@app.route('/parse_xml')
def parse_xml():
xml_src = request.args.get('xml_src')
if not xml_src:
return Response("Missing 'xml_src' parameter.", status=400)
try:
# Parse the XML while disabling外部实体处理

------parser = lxml.etree.XMLParser(resolve_entities=False)
doc = lxml.etree.fromstring(xml_src.encode('utf-8'), parser)
return lxml.etree.tostring(doc)
except lxml.etree.XMLSyntaxError:
return Response('Invalid XML provided.', status=400)
案例研究 3:调试模式安全漏洞 (CWE-094)
一个特别清晰的直接知识转移例子涉及修复 Flask 的调试模式漏洞。在多个实例中,SOSecure 遇到了运行 Flask 在调试模式下的代码:

app.run(debug=True)
相关的 SO 评论隐含提到安全问题,例如:“对于这类项目,最后一行是好习惯,调试器开启非常有用。”
SOSecure 正确地将此识别为仅适用于开发环境的安全建议,并始终做出适当的修复:

app.run(debug=False) # 设置 debug 为 False 用于生产环境
或者更好的方法是:

debug_mode = os.environ.get('FLASK_DEBUG', '0') == '1'
app.run(debug=debug_mode)
这种模式出现在许多示例中,显示了 SOSecure 能够识别何时需要将开发者关注的建议适应于生产安全。
案例研究 4:代码注入风险 (CWE-94)
一个关于更间接知识转移的例子涉及危险的序列化方法。对于以下列表:

r.set("test", pickle.dumps(request.json))
result = pickle.loads(r.get("test"))
检索到的 SO 评论 6 警告:“永远不要在 Web 应用程序中使用‘eval’,因为存在太多攻击向量...”
随后另一条评论回应:“说得有道理。已改为使用‘pickle’而不是‘eval’”
尽管输入代码已经使用了 pickle ,SOSecure 正确回忆起 pickle 同样存在安全风险,并将代码转换为使用更安全的 JSON 序列化:

r.set("test", json.dumps(request.json))
result = json.loads(r.get("test"))
GPT4 在提示修复该片段时没有做出这个改变。

6.1.2 有效社区知识转移中的模式
在分析的示例中,出现了几种 SOSecure 如何有效利用社区知识(当由有能力的 LLM 支持时)的模式。当 SO 评论明确提到安全问题(例如,“不要使用 shell=True”),SOSecure 直接将这些见解应用于其修复中。即使评论没有明确提到漏洞类型,它们通常提供了关于正确框架使用的上下文信息,SOSecure 将这些信息与最佳安全实践相结合。SOSecure 并不盲目应用所有来自 SO 的建议,而是批判性地评估它们的安全影响,正如在 pickle/eval 示例中所见。许多有效的修复利用了关于特定框架实践的社区讨论,例如 Flask 的调试模式,展示了框架专业知识如何促进安全性。这些模式突显了社区知识如何增强 LLM 生成代码的安全性。

6.2 失败案例的定性分析
案例研究 1:SSL/TLS 配置不当 (CWE-327)
在此处,SOSecure 尝试修复一个易受攻击的 SSL 实现:

# 原始易受攻击的代码
context = ssl.create_default_context()
context.check_hostname = True
context.verify_mode = ssl.CERT_REQUIRED

try:
# 假设接收方是一个有效的主机名
with socket.create_connection((recipient, 443)) as sock:
with context.wrap_socket(sock, server_hostname=recipient) as ssl_sock:
ssl_sock.sendall(decrypted_data)
response = ssl_sock.recv(4096)
SO 评论包含有价值的但间接的安全建议: “由于 ‘Poodle’ 漏洞在 SSLv3 中被发现,许多 Web 服务器已禁用了它。你可能需要在
get_server_certificate(...) 调用中添加
ssl_version=ssl.PROTOCOL_TLSv1 ”
虽然 SOSecure 解决了最初标记的漏洞(默认的 SSL/TLS 版本),但修复后的代码仍然存在这个问题:

# 使用 SOSecure 修复的代码(仍易受攻击)
context = ssl.create_default_context()
context.check_hostname = True
context.verify_mode = ssl.CERT_REQUIRED
CodeQL 仍然标记这段代码: “通过调用 \(ssl.create\_default\_context\) 允许不安全的 SSL/TLS 协议版本 TLSv1。”
失败的原因在于 SO 评论提到使用 TLSv1,这现在被认为是不安全的,但没有提到现代应用程序应该使用 TLSv1.2 或更高版本。SOSecure 没有完全更新 SSL 配置以禁用旧协议。这说明了一个挑战:社区讨论可能并不总是反映最新的安全最佳实践。
案例研究 2:弱密码哈希 (CWE-327)
另一个例子中,SOSecure 未能正确解决弱密码哈希实现:

# 原始易受攻击的代码
def getKey(password):
hasher = SHA256.new(password.encode('utf-8'))
return hasher.digest()
尽管 SOSecure 改进了加密和填充机制,但它没有解决 CodeQL 标记的根本问题:使用快速哈希函数(SHA-256)进行密码哈希,这是不安全的,因为它不是一个计算成本高的哈希函数。
SO 评论 7 提到了各种加密问题,但没有具体解决这个弱点: “我在 SO 上看到的一般问题是:1) 加密模式不兼容,2) 密钥大小不兼容 3) KDF 不兼容,4) 忘记 IV,4) 输出编码和解码问题,5) 忘记填充,6) 填充不兼容,..."
SOSecure 应该实现更安全的密码哈希算法,如 bcrypt、Argon2 或 PBKDF2,并采用适当的加盐和迭代次数。此案例表明,当必要的安全指导未在检索到的社区讨论中明确提及时,SOSecure 难以应对。
案例研究 3:接受未知 SSH 主机密钥 (CWE-295)
在第三个涉及使用 Paramiko 进行 SSH 连接的例子中,SOSecure 未能完全保护代码:

# 原始易受攻击的代码
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("hostname", username="username", password="password")
SOSecure 替换了硬编码的凭据,这是一个改进:

# 使用 SOSecure 修复的代码(部分修复)
def connect_sftp(hostname, username):
password = getpass.getpass(prompt='Enter your password: ')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)
return paramiko.SFTPClient.from_transport(ssh.get_transport())
然而,它未能解决 CodeQL 标记的问题:`AutoAddPolicy()` 可能不安全。
SO 讨论没有提到这个安全问题,也没有提供关于 SSH 连接的适当主机密钥验证的指导。这一失败表明,即使 SOSecure 可以改进某些方面的安全性(如凭据处理),如果社区讨论没有涵盖这些问题,它可能会忽略其他关键漏洞。

6.2.1 失败案例中的模式
分析这些和其他失败案例揭示了几种重复出现的情况,其中 SOSecure 无法完全修复安全漏洞。当社区讨论引用过时的安全实践时(例如 TLSv1 曾被认为安全但现在是脆弱的),SOSecure 有时无法辨别这些推荐是否需要更新到当前标准。SOSecure 在需要知识未在检索到的 SO 讨论中明确陈述的情况下表现不佳,这对于特定领域的安全实践尤其具有挑战性。在许多失败案例中,SOSecure 对安全性进行了部分改进,例如替换硬编码凭据或改进错误处理,但忽略了需要专业安全知识才能解决的更深架构或协议级漏洞。当安全决策涉及因上下文而异的可用性和安全性的权衡时,SOSecure 可能缺乏足够的信息来做出最佳决策。我们还发现,检索有时返回专注于调试而非安全的讨论,导致不完整的修复。未来的工作可以通过采样多个互补的讨论来解决这些限制,而不是仅仅使用前 k 个邻居。对于许多模式,甚至可以将 SO 讨论中的所有安全见解汇总成定期更新的知识库,从而产生更短且更有效的重写提示。

6.3 代码相似性分析
由于大多数评估数据集都没有测试用例,我们依赖广泛的手动注释和精心设计的提示,以确保 SOSecure 不会简单地删除代码中的高风险部分来解决漏洞。我们没有发现这样的行为证据。我们还通过计算 SOSecure 对 LMSys 数据集中原始代码和修复代码之间的差异,量化了 SOSecure 对代码所做的修改的平均程度。我们发现,成功的漏洞修复保持了平均相似度为 0.60(使用 Python 的 `difflib` 库,范围从 0 到 1),这表明 SOSecure 正在进行有针对性的安全修改,而不是广泛重写。因此,当支持至少与 GPT4(本文中使用)一样强大的模型时,我们对其保留开发者原意同时解决特定安全问题的能力充满信心。
令牌开销: 将 SO 讨论纳入提示上下文增加了 LLM 查询的输入令牌数量。这种额外的上下文带来了更高的计算成本和延迟,必须在实际部署中加以考虑。我们在 LMSys 的真实世界数据集上测量了这种令牌增加,邻居数量设置为 1,发现 SOSecure 平均每查询增加了约 530 个令牌(使用 tiktoken 8 估算)。

6.4 社区论坛的重要性
SOSecure 在所有三个数据集上的表现验证了我们的核心假设,即社区驱动的安全见解可以有意义地改进 LLM 代码生成。这种有效性源于 SO 讨论相较于 LLM 的关键优势:它们自然捕捉不断演变的安全实践,并迅速适应新发现的漏洞。高严重性漏洞(如 CWE-094、CWE-502)修复率的显著提高表明,SO 讨论提供了关于特定库或 API 使用模式的安全影响的宝贵背景信息,在类似 CWE-078(操作系统命令注入)的案例中,社区评论明确警告了不安全的做法。此外,SO 讨论中捕获的集体智慧代表了来自安全专家、库维护者和各领域经验丰富的开发者的见解,安全知识高度领域特定,漏洞通常与特定框架、库或实现上下文相关。这种多样化的专业知识有助于 SOSecure 有效地应对各种类型的漏洞。
我们工作的一个重要含义涉及社区知识平台(如 SO)与 AI 代码生成工具之间不断变化的关系。随着开发人员越来越多地依赖 LLM 进行代码生成,像 SO 这样的论坛的使用量急剧下降。存在一种风险,即在社区平台上创建的新讨论会减少,更不用说越来越多的这些讨论将是 AI 编写的,可能削弱这一宝贵的资源。正如所示,这也会损害基于 AI 的方法。SOSecure 展示了社区讨论作为 LLM 功能补充的持续价值。

6.5 局限性
CodeQL 准确性约束: 我们的评估依赖于 CodeQL 进行漏洞检测,可能存在误报和漏报。此外,我们的分析仅限于具有现有默认 CodeQL 查询的 CWE 类型,可能遗漏其他重要的漏洞类型。未来的研究可以探索互补的分析技术,以提供更全面的安全评估。
检索策略: SOSecure 的有效性取决于 SO 中安全相关讨论的数量和质量。对于较新或小众技术,社区讨论有限,这种方法可能效果较差。此外,我们使用 BM25 作为检索机制。SOSecure 还可以从开发更复杂的上下文选择过滤机制中受益。

7 结论
本文介绍了 SOSecure,这是一种利用 Stack Overflow 的社区知识来改进 LLM 生成代码安全性的检索增强方法。SOSecure 从包含明确安全警告的帖子和评论中构建了一个以安全为导向的知识库,检索相关讨论,并在代码修订过程中将其作为上下文纳入。我们在三个数据集和两种语言上的评估表明,SOSecure 在缓解安全漏洞方面具有有效性。SOSecure 不需要重新训练或专门微调,允许轻松集成到现有的 LLM 部署中,开销最小。虽然主要评估集中在 Python 上,但 C 语言数据集的结果(表 [tab:llmseceval_combined] )显示 SOSecure 可以跨编程语言推广。此外,随着 Stack Overflow 等平台上的安全讨论不断演变,SOSecure 的知识库可以持续更新,确保在无需重新训练模型的情况下不断提高安全性。


原论文:https://arxiv.org/pdf/2503.1365

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Paper易论

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值