技术速递|如何使用 GitHub Security Lab 的开源 AI 驱动框架进行漏洞扫描

技术速递|如何使用 GitHub Security Lab 的开源 AI 驱动框架进行漏洞扫描 作者Man Yue Mo Peter Stöckli排版Alan WangGitHub Security Lab 的 Taskflow Agent 在发现认证绕过、IDOR、令牌泄露以及其他高影响漏洞方面非常有效。在过去的几个月中我们一直在使用 GitHub Security Lab Taskflow Agent并结合一组新的审计任务流这些任务流专门用于发现 Web 安全漏洞。事实证明它们在开源项目中发现高影响漏洞方面也非常成功。作为安全研究人员我们早已习惯将大量时间花在那些最终无法利用的潜在漏洞上。但借助这些新的任务流我们现在可以把更多时间用于手动验证结果和提交报告。此外我们所报告的漏洞严重性整体都很高其中很多是授权绕过或信息泄露漏洞允许一个用户以他人身份登录或访问其他用户的私有数据。截至目前使用这些任务流我们已经报告了超过 80 个漏洞。在撰写本文时其中大约 20 个已经公开披露。随着新漏洞的披露我们也在持续更新我们的公告页面。在这篇文章中我们将展示一些由这些任务流发现的高影响漏洞的具体示例例如访问电商应用购物车中的个人身份信息PII或者在聊天应用中使用任意密码登录。我们还将解释这些任务流的工作原理以便你学习如何编写自己的任务流。安全社区在知识共享时发展得更快这也是为什么我们将该框架开源并使其能够轻松运行在你自己的项目上。使用和贡献它的团队越多我们共同消除漏洞的速度就越快。GitHub Security Lab Taskflow Agenthttps://github.blog/security/community-powered-security-with-ai-an-open-source-framework-for-security-research/?wt.mc_id3reg_webpage_reactor公告页面https://securitylab.github.com/ai-agents/?wt.mc_id3reg_webpage_reactor访问电商应用购物车中的个人身份信息PIIhttps://github.blog/security/how-to-scan-for-vulnerabilities-with-github-security-labs-open-source-ai-powered-framework/#h-shopping/?wt.mc_id3reg_webpage_reactor在聊天应用中使用任意密码登录https://github.blog/security/how-to-scan-for-vulnerabilities-with-github-security-labs-open-source-ai-powered-framework/#h-signing/?wt.mc_id3reg_webpage_reactor如何在你自己的项目中运行任务流想要立即开始这些任务流是开源的而且很容易自己运行请注意需要 GitHub Copilot 许可证并且这些提示词会使用高级模型请求。注意运行任务流可能会产生大量工具调用从而消耗大量配额。前往 seclab-taskflows 仓库并启动一个 codespace。等待几分钟让 codespace 初始化完成。在终端中运行./scripts/audit/run_audit.sh myorg/myrepo在一个中等规模的代码仓库上运行可能需要一到两个小时。完成后它会打开一个 SQLite 查看器显示结果。打开 “audit_results” 表并查找 “has_vulnerability” 列中带有勾选标记的行。提示由于 LLM 的非确定性特性在同一代码库上多次运行这些审计任务流是值得的。在某些情况下第二次运行可能会产生完全不同的结果。此外你也可以使用不同模型进行多次运行例如第一次使用 GPT 5.2第二次使用 Claude Opus 4.6。这些任务流同样支持私有仓库但你需要修改 codespace 配置因为默认情况下它不会访问你的私有仓库。GitHub Copilothttps://github.com/features/copilot/plans/?wt.mc_id3reg_webpage_reactorseclab-taskflowshttps://github.com/GitHubSecurityLab/seclab-taskflows/?wt.mc_id3reg_webpage_reactor任务流简介任务流是 YAML 文件用于描述我们希望通过 LLM 完成的一系列任务。借助它们我们可以编写提示词来完成不同任务并让任务之间相互依赖。seclab-taskflow-agent 框架负责按顺序运行这些任务并将一个任务的结果传递给下一个任务。例如在审计一个代码仓库时我们首先根据功能将仓库划分为不同组件。然后对于每个组件我们会收集一些信息例如其接收不可信输入的入口点、预期权限以及组件用途等。这些结果会被存储在数据库中为后续任务提供上下文。基于这些上下文数据我们可以创建不同的审计任务。目前我们有一个任务用于为每个组件建议一些通用问题另一个任务则对每个建议问题进行深入审计。当然也可以创建其他任务例如专注于特定类型问题的任务。这些任务会被定义在一个任务流文件中。我们使用任务而不是一个大的提示词是因为 LLM 的上下文窗口有限而且复杂的多步骤任务往往无法正确完成。例如有些步骤可能会被遗漏。即使某些 LLM 拥有更大的上下文窗口我们仍然认为任务流在控制和调试任务以及完成更大更复杂项目方面非常有用。seclab-taskflow-agent 还可以在多个组件上异步运行相同任务类似 for 循环。在审计过程中我们通常对每个组件复用相同的提示词和任务只改变细节。该框架支持定义模板化提示词在运行时遍历组件并替换具体细节。seclab-taskflow-agenthttps://github.com/GitHubSecurityLab/seclab-taskflow-agent/?wt.mc_id3reg_webpage_reactor用于通用安全代码审计的任务流在使用 seclab-taskflow-agent 对 CodeQL 告警进行分类后我们决定不再局限于特定类型漏洞而是探索将该框架用于更通用的安全审计。赋予 LLM 更多自由的主要挑战在于幻觉和误报的增加。之前在处理 CodeQL 告警时的成功部分原因在于我们提供了严格且明确的指令和标准从而可以在每一步验证结果。因此我们的目标是找到一种方法在允许 LLM 自由寻找不同类型漏洞的同时控制幻觉。我们将展示如何通过任务流设计和提示词工程实现高命中率地发现高影响漏洞。对 CodeQL 告警进行分类https://github.blog/security/ai-supported-vulnerability-triage-with-the-github-security-lab-taskflow-agent/?wt.mc_id3reg_webpage_reactor通用任务流设计为了在设计层面减少幻觉和误报我们的任务流从威胁建模阶段开始将仓库按功能划分为组件并收集入口点和用途等信息。这些信息有助于确定每个组件的安全边界以及其暴露于不可信输入的程度。这些信息随后用于判断哪些问题应被视为安全问题。例如在 CLI 工具中如果其功能本身就是执行用户输入的脚本那么命令注入可能是 bug但不一定是安全漏洞。通过威胁建模阶段收集到的信息会被用于确定每个组件的安全边界并判断哪些情况应被视为安全问题。例如一个 CLI 工具若其功能设计为可执行任何用户输入的脚本那么其中存在的命令注入可能只是一个程序缺陷而非安全漏洞因为攻击者若能通过该 CLI 工具注入命令本身就已经可以执行任何脚本了。在提示词层面所发现的组件预期用途和安全边界会被用于提示词中从而为判断发现的问题是否应被视为漏洞提供严格的指导原则。你需要结合组件说明中的用途和威胁模型判断问题是否为真正的安全问题还是预期功能的一部分。可以通过获取入口点、Web 入口点和用户操作来辅助判断。向大语言模型提出像“在代码库的任何地方查找任何类型的漏洞”这样模糊的问题得到的结果会很差还会有很多虚构的问题。理想情况下我们希望模拟分诊环境在这种环境中我们将一些潜在问题作为分析的起点并让大语言模型应用严格的标准来判断该潜在问题是否有效。为了启动这一过程我们将审计任务分为两步首先我们让 LLM 检查代码库的每个组件并指出该组件中更可能出现的漏洞类型。这些建议会被传递到另一项任务中在那里它们将根据严格的标准进行审计。在这种设置中第一步得出的建议就像是由“外部工具”标记的一些不准确的漏洞警报而第二步则起到筛选的作用。虽然这看起来像是一个自我验证的过程——通过将其分解为两个步骤每个步骤都有全新的上下文和不同的提示——但第二步能够对这些建议做出准确的评估。现在我们将详细介绍这些任务。严格的指导原则https://github.com/GitHubSecurityLab/seclab-taskflows/blob/4d8c3db928d131172337eead7c64874a67e59c38/src/seclab_taskflows/prompts/audit/audit_issue.yaml#L16-L18/?wt.mc_id3reg_webpage_reactor威胁建模阶段在对自动代码扫描工具标记的告警进行分流处理时我们发现大量的误报是由于不恰当的威胁建模所导致的。大多数静态分析工具并不会考虑源代码的预期用途和安全边界因此往往会给出并不具备安全意义的结果。例如在反向代理应用中自动化工具标记的许多 SSRF服务器端请求伪造漏洞很可能本就属于该应用的预期使用场景而某些用于持续集成流水线中的 Web 服务本身就是设计用来在沙箱环境中执行任意代码和脚本的。在这些应用中如果不存在逃逸出沙箱的路径那么远程代码执行漏洞通常也不会被视为安全风险。鉴于这些前提首先通读源代码以理解其功能以及预期用途是非常有必要的。我们将这一过程划分为以下几个任务识别应用GitHub 仓库并不是一个完美的审计边界——它可能只是一个更大系统中的单一组件也可能包含多个组件。因此有必要识别并分别审计每个组件以匹配不同的安全边界并保持分析范围可控。我们通过identify_applications这一任务流来实现这一点该任务会让 LLM 检查仓库的源代码和文档并按功能将其划分为不同组件。识别入口点我们识别每个入口点是如何暴露给不可信输入的以更好地评估风险并预测可能的漏洞。由于“非可信输入”在库和应用之间差异很大我们为不同情况提供了分别的指导原则。识别 Web 入口点这是一个额外步骤用于收集应用中入口点的更多信息并补充特定于 Web 应用入口点的信息例如记录访问某个端点所需的 HTTP 方法和路径。识别用户行为我们让 LLM 审查代码并识别用户在正常操作下可以访问的功能。这有助于明确用户的基础权限水平评估漏洞是否可能导致权限提升并帮助定义组件的安全边界和威胁模型同时会根据组件是库还是应用提供不同的指导。在上述每个步骤中收集到的关于仓库的信息都会被存储到数据库中。这些信息包括仓库中的组件、它们的入口点、Web 入口点以及预期用途。这些信息将在下一阶段中被使用。额外步骤https://github.com/GitHubSecurityLab/seclab-taskflows/blob/4d8c3db928d131172337eead7c64874a67e59c38/src/seclab_taskflows/taskflows/audit/gather_web_entry_point_info_local.yaml#L25/?wt.mc_id3reg_webpage_reactor问题建议阶段在这一阶段我们基于前一步收集到的关于入口点和组件预期用途的信息指示 LLM 为每个组件建议可能存在的漏洞类型或指出高安全风险的领域。我们特别强调组件的预期用途以及其面对不可信输入的风险请基于以下内容做出判断- 该组件是否可能接收不可信的用户输入例如远程 Web 请求、IPC 或 RPC 调用- 该组件的预期用途及其功能是什么是否允许执行高权限操作是否对所有用户开放此类功能还是存在复杂的访问控制逻辑- 组件本身可能包含自己的 README.md或其子目录中存在该文件。请查看这些文件以帮助理解组件的功能。我们还明确要求 LLM 不要建议低严重性的问题或通常被认为不是安全问题的问题。但是你仍然需要注意不要包含那些严重性较低或需要不现实攻击场景例如错误配置或系统已被攻破的情况。总体而言我们在这一阶段保持较少的限制让 LLM 有自由去探索并建议不同类型的漏洞和潜在安全问题。其目的是为后续的审计任务提供一个合理的关注范围和漏洞类型集合作为起点。我们遇到的一个问题是LLM 有时会开始对其提出的问题进行审计这会破坏头脑风暴阶段的目的。为避免这一点我们明确指示 LLM 不要对问题进行审计。基于前一步收集到的关于入口点和组件预期用途的信息https://github.com/GitHubSecurityLab/seclab-taskflows/blob/4d8c3db928d131172337eead7c64874a67e59c38/src/seclab_taskflows/taskflows/audit/classify_application_local.yaml#L50-L55/?wt.mc_id3reg_webpage_reactor不要对问题进行审计https://github.com/GitHubSecurityLab/seclab-taskflows/blob/4d8c3db928d131172337eead7c64874a67e59c38/src/seclab_taskflows/taskflows/audit/classify_application_local.yaml#L78/?wt.mc_id3reg_webpage_reactor问题审计阶段这是任务流的最后一个阶段。在我们收集了关于仓库的所有必要信息并提出了一些需要重点关注的漏洞类型和安全风险之后任务流会逐个对这些建议的问题进行源码审计。在这一阶段任务会以全新的上下文开始以审查前一阶段提出的问题。这些建议被视为未经验证的任务流会被指示去验证这些问题这些建议的问题尚未被正确验证它们只是因为在这类应用中较为常见而被提出。你的任务是审计源代码以确认这些问题是否真实存在。为了避免 LLM 在该组件的上下文中提出非安全相关的问题我们再次强调必须考虑其预期用途你需要结合组件说明中的意图和威胁模型来判断一个问题是否是真正的安全问题还是预期功能的一部分。为了避免 LLM 幻觉出不现实的问题我们还要求其提供具体且现实的攻击场景并且只考虑源代码中的错误所导致的问题不要考虑通过窃取凭据等方式绕过认证的场景。我们只考虑那些可以从源代码本身实现的情况。……如果你认为存在漏洞那么你必须提供一个现实的攻击场景包含所有相关文件和行号的细节以及攻击者通过利用该漏洞能够获得什么收益。只有当攻击者能够通过执行组件未预期的操作获得权限提升时才将该问题视为漏洞。为了进一步减少幻觉我们还要求 LLM 提供来自源代码的具体证据包括文件路径和行号请记录审计笔记务必包含所有相关文件路径和行号。仅仅陈述一个端点例如 IDOR in user update/delete endpoints (PUT /user/:id) 是不够的我需要具体的文件和行号。最后我们还告知 LLM组件中可能根本不存在漏洞不应凭空捏造请记住这些建议的问题仅仅是推测可能完全不存在漏洞得出“没有安全问题”的结论也是可以接受的。这一阶段的重点是在遵循严格规范的同时提供准确结果并给出具体证据。在这些严格指示下LLM 确实能够拒绝大量不现实或不可利用的建议同时几乎不会产生幻觉。最初的原型设计优先考虑减少幻觉这也引出了一个问题它是否会变得过于保守从而拒绝大多数漏洞候选无法发现真实问题在我们将任务流运行在多个仓库之后答案已经非常清晰。未经验证的https://github.com/GitHubSecurityLab/seclab-taskflows/blob/4d8c3db928d131172337eead7c64874a67e59c38/src/seclab_taskflows/prompts/audit/audit_issue.yaml#L9/?wt.mc_id3reg_webpage_reactor由任务流发现的三个漏洞示例在本节中我们将展示三个由任务流发现并已经披露的漏洞示例。到目前为止我们已经发现并报告了超过 80 个漏洞。所有已披露漏洞都会发布在我们的公告页面上。公告页面https://securitylab.github.com/advisories/?wt.mc_id3reg_webpage_reactorOutline 中的权限提升CVE-2025-64487我们的信息收集任务流针对 Web 应用进行了优化因此我们首先将审计任务流应用于一个名为 Outline 的协作型 Web 应用。Outline 是一个多用户协作套件其特点包括文档具有所有者和不同的可见性并基于用户和团队设置权限这种访问规则难以通过静态应用安全测试SAST工具分析因为它们使用自定义访问机制而现有工具通常无法判断一个普通“用户”应具备哪些操作权限对人类来说仅通过阅读源代码来分析此类权限模型同样困难除非你是该模型的设计者。并且成功了我们的任务流在第一次运行中就发现了授权逻辑中的一个漏洞审计结果中的记录如下审计目标outline/outline 的组件服务后端 API组件 ID 2中存在不当的成员管理授权问题。总结结论确实存在一个权限提升漏洞。文档分组成员关系修改的接口documents.add_group、documents.remove_group在进行授权时使用了较弱的 “update” 权限而不是用户成员变更所需的更强权限 “manageUsers”。由于仅拥有文档的 ReadWrite 成员权限即可满足 “update”因此一个非管理员的文档协作者可以授予或撤销分组成员关系——包括授予 Admin 权限——从而提升其自身如果其属于被添加的组以及其他组成员的权限。这使其能够执行原本不应赋予仅具备 ReadWrite 权限协作者的操作例如 manageUsers、archive、delete 等。通过阅读基于 TypeScript 的源代码并在测试实例中验证该发现可以确认该漏洞完全可以按描述方式被利用。此外所描述的利用步骤也是准确的前提条件- 攻击者是普通团队成员非管理员不是访客对文档 D 拥有直接的 ReadWrite 成员权限或通过某个授予 ReadWrite 的分组获得但不是 Admin。- 攻击者是同一团队中现有分组 G 的成员无需是该分组的管理员根据分组策略拥有读取权限即可。步骤1. 攻击者调用 POST documents.add_groupserver/routes/api/documents/documents.ts 第 1875-1926 行请求体如下{id: document-D-id,groupId: group-G-id,permission: admin}2. 授权路径- 第 1896 行authorize(user, update, document) 成功因为攻击者拥有 ReadWrite 成员权限document.ts 第 96-99 行允许 update。- 第 1897 行authorize(user, read, group) 成功因为任意同团队的非访客用户都具备该权限group.ts 第 27-33 行。未进行 “manageUsers” 权限检查。3. 代码创建或更新 GroupMembership并赋予 Admin 权限第 1899-1919 行。4. 由于攻击者属于分组 G其对文档的实际权限通过 groupMembership现在包含 DocumentPermission.Admin。5. 拥有 Admin 成员权限后攻击者即可满足 includesMembership(Admin)从而执行以下操作- manageUsersdocument.ts 第 123-134 行可以通过 documents.add_user / documents.remove_user第 1747-1827 行、1830-1872 行添加或移除任意用户- archive / unarchive / deletedocument.ts 中 archive 策略第 241-252 行delete 第 198-208 行影响内容完整性- duplicate、move 以及其他类似管理员的操作例如 duplicate 策略第 136-153 行move 第 155-170 行超出原本 ReadWrite 权限范围。按照上述步骤一个低权限用户可以向其仅具备更新权限的文档中添加任意分组即该用户并不具备通常执行此类操作所需的 “manageUsers” 权限。在该示例中名为 “gg” 的低权限用户将分组 “Support” 添加到了该文档中。Outline 项目在三天内修复了该问题以及我们报告的另一个问题。公告Outlinehttps://www.getoutline.com/?wt.mc_id3reg_webpage_reactor公告https://github.com/outline/outline/security/advisories/GHSA-c8xf-3j86-7686/?wt.mc_id3reg_webpage_reactor购物车灾难CVE-2025-15033, CVE-2026-25758我们最初并没有意识到当我们将任务流应用于列表中的第一个在线商店时会在电商应用的购物车逻辑中发现如此系统性的问题。在基于 PHP 的 WooCommerce 项目中任务流很快就发现了一种方式使得普通已登录的商店用户可以查看所有访客订单——其中包括可识别个人身份的信息例如姓名、地址和电话号码。在我们报告该问题后AutomatticWooCommerce 的开发公司迅速发布了更新CVE-2025-15033以及相关的博客说明。受到这一漏洞的启发我们将更多电商应用加入了由智能体审计的应用列表。果然我们又发现了新的漏洞。流行的基于 Ruby 的 Spree Commerce 应用中包含两个类似漏洞CVE-2026-25758 和 CVE-2026-25757。其中更严重的一个漏洞允许未认证用户通过简单地递增一个顺序编号就可以枚举出所有访客订单的地址以及电话号码。在下方截图中攻击者“test66”将自己的会话关联到了一个现有的访客用户地址从而能够查看该用户的完整地址和电话号码。我们的漏洞挖掘之旅并未止步于 Spree Commerce。我们的任务流在另外两个电商应用中也发现了类似的问题。这些授权逻辑漏洞多年未被发现。CVE-2025-15033https://github.com/advisories/GHSA-q45j-x3cj-gjvq/?wt.mc_id3reg_webpage_reactor博客说明https://developer.woocommerce.com/2025/12/22/store-api-vulnerability-patched-in-woocommerce-8-1/?wt.mc_id3reg_webpage_reactorSpree Commercehttps://spreecommerce.org/?wt.mc_id3reg_webpage_reactorCVE-2026-25758https://github.com/spree/spree/security/advisories/GHSA-87fh-rc96-6fr6/?wt.mc_id3reg_webpage_reactorCVE-2026-25757https://github.com/spree/spree/security/advisories/GHSA-p6pv-q7rc-g4h9/?wt.mc_id3reg_webpage_reactor使用任意密码登录 Rocket.ChatCVE-2026-28514这并不是无密码认证应该呈现的样子有时候你会不敢相信自己的眼睛。我们的任务流在 Rocket.Chat 中报告的这个发现就是这样的时刻之一。当你的智能体返回这样一条记录时漏洞账号服务中的密码认证绕过允许在设置了密码的情况下以任意用户身份登录。你一开始可能很难相信。当你继续阅读输出内容时根本原因- ee/apps/account-service/src/lib/utils.ts:60-61validatePassword 返回的是 Promiseboolean即 bcrypt.compare(...)。- ee/apps/account-service/src/lib/loginViaUsername.ts:18-21const valid user.services?.password?.bcrypt validatePassword(password, user.services.password.bcrypt); 但这里没有对 Promise 使用 await由于 Promise 本身是真值因此当 bcrypt 哈希存在时if (!valid) return false; 永远不会被触发。- ee/apps/account-service/src/lib/loginViaUsername.ts:23-35代码继续生成新的登录令牌并保存返回 { uid, token, hashedToken, tokenExpires }。这样看起来可能更合理了一些但你仍然会心存疑虑。事实证明这个疑似漏洞出现在 Rocket.Chat 的微服务架构部署中。在该特定架构下Rocket.Chat 通过其 DDP Streamer 服务对外暴露用户账户服务。Rocket.Chat 的微服务部署架构 版权归 Rocket.Chat 所有。该架构图来自 Rocket.Chat 的官方文档。在我们的 Rocket.Chat 测试环境正常运行后我们需要编写概念验证代码来利用这一潜在漏洞。智能体的记录中已经包含了一个 JSON 构造体可用于通过 Meteor 的 DDP 协议连接到相应的端点。我们连接到了该 DDP Streamer 服务的 WebSocket 端点结果证明确实可以使用任意密码登录暴露的 Rocket.Chat DDP 服务。一旦成功登录还可以执行其他操作例如连接到任意聊天频道并监听这些频道中的消息。在这里我们在监听 “General” 频道时收到了消息 “HELLO WORLD!!!”。这个问题的技术细节既有意思也令人有些担忧。Rocket.Chat 是一个主要基于 TypeScript 的 Web 应用它使用 bcrypt 来存储本地用户密码。bcrypt.compare函数用于将输入密码与存储的哈希值进行比较返回的是一个 Promise——这一点也体现在 Rocket.Chat 自身的validatePassword函数中该函数返回Promiseboolean。export const validatePassword (password: string, bcryptPassword: string): Promiseboolean bcrypt.compare(getPassword(password), bcryptPassword);然而在实际使用该函数时并没有对 Promise 的结果进行正确处理例如在validatePassword前添加await关键字。const valid user.services?.password?.bcrypt validatePassword(password, user.services.password.bcrypt); if (!valid) { returnfalse;}这导致validatePassword的返回值被与true进行逻辑“与AND”运算。由于在 JavaScript 中Promise 对象本身始终被视为“truthy”因此当用户设置了 bcrypt 密码时valid变量实际上始终为true。抛开严重性不谈这件事本身也很有意思LLM 能够识别出这样一个相当隐蔽的 bug跨多个文件追踪其影响并最终得出正确结论这一点确实令人印象深刻。CVE-2026-28514https://github.com/RocketChat/Rocket.Chat/security/advisories/GHSA-w6vw-mrgv-69vf/?wt.mc_id3reg_webpage_reactorPromisehttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/?wt.mc_id3reg_webpage_reactor我们学到了什么在对 40 多个代码仓库主要是多用户 Web 应用运行任务流之后LLM 共提出了 1,003 个问题潜在漏洞。在审计阶段之后其中 139 个被标记为存在漏洞即 LLM 认为这些问题是可利用的。在去重之后——由于每个仓库平均会运行多次任务流结果会被汇总因此会产生重复项——最终得到 91 个漏洞我们在正式报告前对这些漏洞进行了人工审查。我们拒绝了其中 20 个22%结果判定为 FP这些问题无法通过手动复现。我们拒绝了 52 个57%结果判定为低严重性问题这些问题潜在影响非常有限例如仅返回 HTTP 状态码的盲 SSRF、需要在安装阶段存在恶意管理员才能触发的问题等。最终我们仅保留了 19 个21%我们认为具有足够影响力、值得报告的漏洞。这些均为严重漏洞其中大多数属于高危或严重级别例如无需特定条件即可触发、并影响机密性或完整性的漏洞如个人数据泄露、系统配置被覆盖、账户接管等。上述数据使用gpt-5.x作为代码分析与审计任务的基础模型进行收集。需要注意的是在这些数据收集之后我们又在更多仓库上运行了任务流因此该表格并不代表我们收集的全部数据也不代表我们已报告的全部漏洞。漏洞类别总数存在漏洞漏洞发生率越权 / 访问控制漏洞2413815.8%XSS1311713.0%CSRF1101715.5%身份认证漏洞911516.5%安全配置不当751317.3%路径遍历漏洞611016.4%SSRF45715.6%命令注入漏洞39512.8%远程代码执行2414.2%业务逻辑漏洞24625.0%模板注入漏洞2414.2%文件上传处理漏洞不含路径遍历18211.1%不安全反序列化1700.0%开放重定向漏洞1600.0%SQL 注入漏洞900.0%敏感信息泄露800.0%XXE400.0%内存安全问题300.0%其他66710.6%如果我们将这些发现粗略分为两类——逻辑类问题IDOR、认证问题、安全配置错误、业务逻辑问题、敏感数据泄露和技术类问题XSS、CSRF、路径遍历、SSRF、命令注入、远程代码执行、模板注入、文件上传问题、不安全反序列化、开放重定向、SQL 注入、XXE、内存安全问题——那么可以得到 439 个逻辑类问题和 501 个技术类问题。虽然技术类问题数量更多但差异并不显著因为某些宽泛类别例如远程代码执行和文件上传问题在不同攻击场景下也可能涉及逻辑层面的缺陷。在所有建议问题中只有 3 个与内存安全相关。这一点并不太令人意外因为大多数被测试的代码仓库都是使用内存安全语言编写的。不过我们也怀疑目前的任务流在发现内存安全问题方面效率并不高尤其是与其他自动化工具例如 fuzzers相比时更是如此。这是一个值得改进的有趣方向可以通过创建更专门化的任务流并让 LLM 能够使用更多工具例如 fuzzers来提升效果。这些数据最终促成了我们以下的一些观察结论。对 CodeQL 告警进行分类https://github.blog/security/ai-supported-vulnerability-triage-with-the-github-security-lab-taskflow-agent/?wt.mc_id3reg_webpage_reactorLLM 在发现逻辑漏洞方面表现尤为出色从数据中最突出的点是“业务逻辑问题”占比达到 25%以及大量的 IDOR 问题。事实上被标记为存在漏洞的 IDOR 数量甚至超过了接下来两个类别XSS 和 CSRF的总和。总体来看我们的印象是LLM 在理解代码空间、跟踪控制流方面表现非常出色同时能够结合访问控制模型和应用的预期使用方式进行推理——这基本符合我们对擅长代码审查任务的 LLM 的预期。这也使得它在发现传统工具难以检测的逻辑漏洞方面非常有优势。LLM 擅长识别低严重性问题与误报有趣的是所有误报都不属于我们通常意义上的“幻觉”。所有报告包括误报都具备合理的证据支撑我们也能够顺着报告找到对应接口并复现其建议的 payload。许多误报来自代码之外的更复杂情境例如前面提到的 XSS 浏览器级缓解机制或者是人类审计员也可能犯的真实判断错误。例如在存在多层认证逻辑时LLM 有时会遗漏某一层检查从而导致误报。在后续测试中我们在更多仓库上运行了任务流并报告了更多漏洞但“漏洞数量与仓库数量之间的比例”基本保持稳定。为了展示任务流的可扩展性以及如何将额外信息融入流程我们在审计阶段之后新增了一个任务流用于结合新获得的知识过滤低严重性漏洞。结果显示该任务流可以过滤掉大约 50% 的低严重性问题同时也有少量我们原本报告的边界案例被归类为低严重性。任务流和提示词都可以根据用户偏好进行调整但对我们来说更倾向于保持“更包容”的策略以避免遗漏任何有影响力的问题。任务流https://github.com/GitHubSecurityLab/seclab-taskflows/blob/f7db21ea6aa250373249a5225e1c63b4ea27da2e/src/seclab_taskflows/taskflows/audit/filter_severity.yaml#L1/?wt.mc_id3reg_webpage_reactorLLM 擅长威胁建模总体而言LLM 在威胁建模方面表现良好。在实验中我们在多种不同威胁模型的应用上进行了测试例如桌面应用、多租户 Web 应用、设计用于在沙箱中执行代码的应用本身允许代码注入、以及反向代理类应用其中 SSRF 类行为是设计功能。任务流能够考虑这些应用的预期用途并做出合理判断。但在桌面应用的威胁建模方面表现最弱因为通常很难判断用户桌面上运行的其他进程是否应被视为可信。我们还观察到一些令人印象深刻的推理能力例如 LLM 能够排除那些没有带来权限提升的“问题”。例如在一个案例中LLM 识别到虽然访问控制存在不一致但攻击者并不会比手动复制粘贴获得任何额外优势安全影响评估仅拥有文档只读权限的用户没有更新权限如果同时拥有目标集合的 updateDocument 权限可以复制该文档并创建可编辑副本。这并不会赋予其对其他文档的额外访问权限也不会绕过原始文档的保护任何拥有读取权限的用户都可以手动复制粘贴内容到其有权限创建的新文档中在 ReadWrite 集合的 createDocument 策略下通常非 guest、非 viewer 成员允许创建文档。我们也观察到一些更复杂的推理技巧。例如在一个运行于 Node.js 沙箱环境中的应用中LLM 提出了一种逃逸沙箱的方法在 Node 的 vm 模块中如果将外部作用域的函数传入情境化沙箱该函数的 constructor 属性可能泄露外部作用域的 Function 构造器。在沙箱内部可以这样利用const F console.log.constructor; // 外部作用域 Functionconst hostProcess F(return process)(); // 获取宿主 process 对象// 通过动态 import 绕过模块白名单const cp await F(return import(node:child_process))();const out cp.execSync(id).toString();return [{ json: { out } }];宿主函数如 console.log、timers、require、RPC 方法的存在足以获取宿主的 Function 构造器并逃逸沙箱。require-resolver 的白名单可以通过构造宿主作用域函数并使用动态 import 内置模块如 node:child_process绕过而该过程不会经过沙箱的自定义 require 逻辑。尽管最终由于其他缓解机制这个结果被证明是误报但它很好地展示了 LLM 的技术理解能力。参与进来我们用于发现这些漏洞的任务流已开源并且可以轻松在你的项目中运行。我们也鼓励你编写自己的任务流。本文展示的结果只是能力的一小部分示例。还有更多类型的漏洞可以被发现也有更多安全相关问题如 SAST 结果分流或开发环境构建可以借助任务流解决。欢迎在我们的仓库中发起讨论告诉我们你在构建什么任务流https://github.com/GitHubSecurityLab/seclab-taskflows/?wt.mc_id3reg_webpage_reactor编写自己的任务流https://github.blog/security/community-powered-security-with-ai-an-open-source-framework-for-security-research/?wt.mc_id3reg_webpage_reactorSAST 结果分流https://github.blog/security/ai-supported-vulnerability-triage-with-the-github-security-lab-taskflow-agent/?wt.mc_id3reg_webpage_reactor在我们的仓库中发起讨论https://github.com/GitHubSecurityLab/seclab-taskflow-agent/discussions/categories/show-and-tell/?wt.mc_id3reg_webpage_reactor