
1. 为什么我们需要一个专门的代码安全审查技能代码审查这件事做过的人都知道它本质上是一个“找茬”的活儿。但找茬和找茬之间差别巨大——有人盯的是命名规范、缩进空格有人盯的是逻辑漏洞、边界条件而真正要命的那一类问题往往藏在安全层面一个没做校验的输入参数、一处硬编码的密钥、一段看似无害却能被构造利用的字符串拼接。security-audit-skill这个项目标题核心指向的就是把“安全审查”这件事从人工经验中抽离出来做成一个可复用、可迭代、可被 AI 调用的技能模块。它不是一个完整的静态扫描工具也不是一个 CI/CD 流水线插件而更像是一份“审查员的思维清单 执行手册”让 AI 在审查代码时能够按照固定的安全维度逐项过筛而不是随机地凭感觉挑毛病。我最初接触这类需求是因为团队里代码审查的质量波动太大。同一个 PR资深安全工程师能挑出五六个问题普通开发同学可能只看到两个明显的。这不是能力问题而是没有一套标准化的审查路径。security-audit-skill要解决的正是这个“路径标准化”的问题——把安全审查拆解成可枚举的检查项每一项都有明确的判断依据和输出格式AI 按照这个框架走就不会漏掉关键维度。这篇文章适合三类人看一是正在搭建 AI 辅助代码审查流程的工程师二是想把自己安全审查经验沉淀成可复用资产的团队负责人三是对 AI 代码审查能力边界感兴趣的技术管理者。我会从设计思路、核心检查项拆解、实操落地方式、常见误报与排查四个层面展开尽量把每个决策背后的“为什么”讲清楚。2. 安全审查技能的整体设计思路2.1 为什么不做成纯规则引擎很多人第一反应是安全审查不就是写规则吗正则匹配password、检测eval(、扫描SELECT * FROM一套规则库跑下来不就完了我试过这条路结论是规则引擎能覆盖 60% 的明显问题但剩下 40% 才是真正危险的。原因在于安全漏洞的判定高度依赖上下文。同样是字符串拼接在日志输出里是正常的在 SQL 查询里就是注入风险同样是md5调用用于文件校验没问题用于密码存储就是严重缺陷。规则引擎看不到上下文只能一刀切结果就是大量误报把真正的问题淹没。security-audit-skill的设计思路是“规则提供线索AI 做上下文判断”。技能模块里定义的是检查维度和判断逻辑而不是死板的匹配模式。比如“输入校验”这个维度技能不会要求 AI 去匹配某个函数名而是引导 AI 去追踪数据流这个参数从哪里来、经过了哪些处理、最终流向哪里、中间有没有做类型和范围校验。2.2 技能模块的组成结构一个完整的security-audit-skill通常包含四个部分审查维度清单把安全审查拆成若干大类每类下有具体的检查点。这是技能的骨架。判断依据说明每个检查点为什么重要、什么样的代码算有问题、什么样的算安全。这是技能的血肉。输出格式模板审查结果怎么组织问题怎么分级修复建议怎么写。这是技能的出口。上下文获取策略AI 在审查时需要看哪些文件、追踪哪些调用链、如何获取足够的上下文。这是技能的执行保障。这四部分缺一不可。我见过不少团队只写了维度清单结果 AI 审查出来的东西要么太泛“建议加强输入校验”要么太偏盯着无关紧要的格式问题不放。问题就出在缺少判断依据和输出约束。2.3 审查维度的选取逻辑安全审查的维度不是越多越好。维度太多AI 的注意力被分散每个维度都浅尝辄止维度太少覆盖不全漏掉关键风险。我的经验是围绕“数据流”来组织维度而不是围绕“漏洞类型”。因为漏洞类型是结果数据流才是原因。一个典型的 Web 服务代码数据从入口到出口会经过请求解析、参数校验、业务逻辑、数据持久化、响应构造。每个环节都有对应的安全关注点。具体来说security-audit-skill通常覆盖以下六个核心维度维度关注点典型风险输入处理参数来源、类型校验、边界检查注入、越界、类型混淆认证授权身份验证、权限判定、会话管理越权、身份伪造数据存储敏感数据加密、密钥管理、日志脱敏信息泄露外部调用第三方接口、命令执行、文件操作命令注入、路径穿越错误处理异常捕获、错误信息暴露、降级策略信息泄露、拒绝服务依赖安全第三方库版本、已知漏洞、许可证供应链风险这六个维度不是拍脑袋定的而是从实际审查中反复验证出来的。每一条都对应着真实项目中出现过的问题。比如“错误处理”这个维度很多人觉得不重要但我实际遇到过因为异常堆栈直接返回给前端导致数据库表结构泄露的案例。2.4 与通用代码审查的区别通用代码审查关注的是可读性、可维护性、性能、风格一致性。安全审查关注的是“这段代码在恶意输入下会怎样”。两者的视角完全不同。举个例子一段代码用了复杂的嵌套三元表达式通用审查会说“可读性差建议拆开”安全审查不关心这个它关心的是“这个表达式的分支条件是否覆盖了所有边界有没有可能因为某个分支未处理而导致权限绕过”。security-audit-skill的定位很明确它不替代通用审查而是在通用审查之后增加一道安全专项。两者可以并行但关注点必须分开否则 AI 会在风格问题上浪费大量注意力。3. 核心检查项的拆解与判断依据3.1 输入处理从“有没有校验”到“校验够不够”输入处理是安全审查的第一道关也是最容易出问题的地方。很多开发者知道要做校验但校验的粒度往往不够。我在技能模块里把输入处理拆成四个检查点第一参数来源是否可信。来自请求体、查询字符串、路径参数、请求头的值默认都不可信。来自配置文件、环境变量、内部服务调用的值可信度稍高但也不能完全信任。AI 在审查时需要追踪每个参数的来源标记出所有外部输入点。第二类型和格式校验是否完整。只检查“非空”是不够的。一个期望是整数的参数如果只做了非空检查攻击者传入1; DROP TABLE就可能出问题。技能模块要求 AI 检查类型是否匹配、长度是否受限、格式是否符合预期、取值范围是否合理。第三边界条件是否覆盖。空字符串、超长字符串、负数、零、最大值、最小值、特殊字符这些边界值有没有被处理。我见过一个案例分页参数pageSize没有上限攻击者传了1000000直接把数据库拖垮。第四校验失败后的行为是否安全。校验失败是返回默认值、抛异常、还是继续执行如果继续执行那校验等于没做。技能模块要求 AI 明确追踪校验失败后的控制流。实操心得输入校验的审查不要只看校验代码本身要看校验之后的数据流。很多漏洞不是因为没有校验而是因为校验后的数据被重新赋值或转换导致校验失效。3.2 认证授权最容易“看起来没问题”的维度认证和授权的代码往往写得很“整洁”函数名清晰、逻辑分支明确但恰恰是这种整洁容易让人放松警惕。技能模块在这个维度下设置三个检查点认证绕过检查。重点看是否存在“默认通过”的分支。比如if (user null) { return true; }这种逻辑表面上是处理空用户实际上可能被利用来绕过认证。AI 需要检查所有认证函数的返回路径确认没有意外的放行分支。权限判定粒度。很多系统只做了“是否登录”的检查没有做“是否有权限操作这个资源”的检查。技能模块要求 AI 追踪资源 ID 的来源确认权限判定是否绑定到了具体资源。比如删除操作不能只检查“用户已登录”还要检查“这个用户是否有权删除这条记录”。会话与令牌管理。令牌的生成是否随机、有效期是否合理、失效机制是否完善、是否在日志中泄露。这些点看起来琐碎但每一个都可能成为突破口。我实际审查过一个项目认证逻辑写得没问题但令牌的过期时间设置成了 30 天而且没有刷新机制。这意味着一旦令牌泄露攻击者可以长期使用。这种问题规则引擎扫不出来只有理解业务上下文才能发现。3.3 数据存储敏感信息的“最后一公里”数据存储维度的核心问题是敏感数据在落盘时是否得到了足够的保护。技能模块的检查点包括敏感字段识别。哪些字段算敏感密码、手机号、身份证号、银行卡号、地址、邮箱这些是常规的。但不同业务还有特定的敏感字段比如医疗记录、交易金额、内部标识。技能模块要求 AI 结合代码中的字段命名和注释来判断而不是只依赖固定列表。加密与哈希的使用。密码必须用慢哈希bcrypt、scrypt、argon2不能用 md5、sha1、sha256 直接存。对称加密的密钥不能硬编码在代码里。这些是硬性要求AI 需要逐项核对。日志与错误信息脱敏。敏感数据不能出现在日志里也不能出现在错误响应里。我见过把用户密码打印到调试日志的代码也见过把数据库连接字符串拼到异常信息里返回给前端的。技能模块要求 AI 检查所有日志输出点和异常处理点。数据访问权限。数据库账号的权限是否最小化有没有用 root 账号连接业务库跨库查询是否受控。这些偏运维层面但在代码审查中也能看到线索比如连接字符串的配置。3.4 外部调用信任边界的把控外部调用包括调用第三方 API、执行系统命令、操作文件系统、访问网络资源。这些操作的共同点是一旦参数被控制后果可能非常严重。技能模块在这个维度的检查逻辑是“追踪参数到危险函数”命令执行类exec、system、popen、subprocess等检查参数是否来自外部输入是否做了白名单过滤。文件操作类open、read、write、delete检查路径是否可控是否做了路径规范化是否限制了访问目录。网络请求类检查目标 URL 是否可控是否存在 SSRF 风险是否限制了内网地址访问。反序列化类检查反序列化的数据来源是否使用了安全的序列化格式。这里的关键是“白名单优于黑名单”。黑名单永远列不全白名单才能有效控制。技能模块会引导 AI 判断这里的过滤是白名单还是黑名单白名单的覆盖范围是否合理3.5 错误处理被忽视的信息泄露通道错误处理在通用审查中往往被当作“健壮性”问题但在安全审查中它是信息泄露的主要通道。技能模块要求 AI 检查异常是否被捕获后直接返回给调用方包含堆栈信息、SQL 语句、文件路径等敏感内容。是否存在“吞异常”的情况即捕获后不做任何处理导致问题被掩盖。降级策略是否安全比如认证服务不可用时是拒绝所有请求还是放行所有请求。错误码和错误信息是否区分了“用户输入错误”和“系统内部错误”避免给攻击者提供探测线索。我踩过的一个坑是某个接口在参数校验失败时返回了详细的字段类型和长度要求攻击者据此可以推断出数据库表结构。后来改成统一的“参数错误”提示虽然对调试不友好但安全性提升明显。3.6 依赖安全供应链的隐形风险依赖安全是近年来才被重视的维度。技能模块的检查点包括依赖库的版本是否过旧是否存在已知的高危漏洞。是否引入了不必要的依赖增加了攻击面。依赖的来源是否可信有没有使用来路不明的包。许可证是否合规避免法律风险。这个维度 AI 做起来有天然优势它可以快速比对依赖列表和公开的漏洞数据库给出风险提示。但要注意AI 的知识有截止日期最新的漏洞信息需要结合外部数据源。4. 实操落地如何让 AI 真正执行安全审查4.1 技能模块的加载方式security-audit-skill作为一个技能需要被 AI 在审查任务开始前加载。加载方式取决于你使用的 AI 平台但核心逻辑是一样的把技能内容作为系统提示或上下文的一部分注入。我通常的做法是分两步第一步把技能模块的“审查维度清单”和“判断依据说明”作为系统提示注入让 AI 建立审查框架。第二步把待审查的代码文件、相关的调用链文件、配置文件作为用户输入提供让 AI 在具体上下文中执行审查。这里有个细节不要一次性把整个代码库丢给 AI。上下文太长AI 的注意力会分散审查质量反而下降。我的经验是每次审查 3-5 个相关文件聚焦一个功能模块或一条数据流。4.2 审查任务的描述模板给 AI 下审查指令时描述越具体输出质量越高。我常用的模板是这样的请使用 security-audit-skill 对以下代码进行安全审查。 审查范围 - 文件列表[列出文件] - 功能描述[简要说明这段代码做什么] - 数据流[说明数据从哪里来、到哪里去] 输出要求 - 按审查维度分组 - 每个问题标注严重等级高/中/低 - 每个问题给出具体代码位置和修复建议 - 如果没有发现问题明确说明“该维度未发现明显问题”这个模板的关键是“数据流”那一项。很多 AI 审查效果不好就是因为没有告诉它数据是怎么流动的。AI 自己追踪数据流的能力有限给它一个明确的起点和终点审查精度会大幅提升。4.3 严重等级的定义标准严重等级不能凭感觉定需要有明确标准。我在技能模块里定义了三档高危可直接导致数据泄露、权限绕过、远程代码执行的问题。比如 SQL 注入、硬编码密钥、命令注入。中危需要一定条件才能利用或影响范围有限的问题。比如日志泄露敏感信息、错误信息暴露内部结构、依赖库存在中危漏洞。低危最佳实践类问题不直接导致安全事件但增加了风险。比如密码强度校验不足、会话超时时间过长。这个分级标准要写进技能模块让 AI 在输出时自动标注。否则 AI 会把所有问题都标成“高危”反而失去了分级的价值。4.4 审查结果的验证与反馈AI 审查出来的结果不能直接采信需要人工验证。我的做法是先快速过一遍所有“高危”问题确认是否真实存在。这一步通常能过滤掉 20%-30% 的误报。然后看“中危”问题判断是否值得修复。有些中危问题在当前业务场景下其实不构成风险可以标记为“已知晓暂不修复”。最后看“低危”问题作为代码改进的参考。验证过程中发现的误报和漏报要反馈到技能模块里。比如某个检查点经常误报就调整判断依据某个漏洞类型经常漏掉就增加检查点。技能模块是迭代出来的不是一次写好的。5. 常见误报与排查技巧实录5.1 误报的典型模式AI 安全审查的误报主要集中在几类上下文缺失导致的误报。AI 看到md5就报“弱哈希”但这个md5可能只是用来生成缓存键不涉及密码存储。解决办法是在审查指令中明确说明哪些字段是敏感字段或者让 AI 在报告前先确认“这个函数的输出是否用于安全目的”。框架封装导致的误报。现代框架通常内置了安全防护比如 ORM 自动参数化查询、模板引擎自动转义。AI 如果只看表面代码可能会把框架的安全机制当成漏洞。解决办法是让 AI 先识别使用的框架和版本再判断代码是否绕过了框架的安全机制。测试代码和示例代码的误报。测试文件里经常有硬编码的假密钥、故意构造的恶意输入。这些不是真实漏洞。解决办法是在审查范围中排除测试目录或者让 AI 标注“疑似测试代码需人工确认”。5.2 漏报的常见原因漏报比误报更危险因为误报只是浪费验证时间漏报可能导致真实漏洞被放过。数据流追踪中断。AI 追踪一个参数从入口到危险函数中间经过多层函数调用如果某一层没有提供代码追踪就断了。解决办法是提供完整的调用链文件或者在指令中说明“如果调用链不完整请标注需要补充的文件”。间接依赖未覆盖。代码本身没问题但依赖的第三方库有漏洞。AI 如果只审查业务代码就会漏掉这类问题。解决办法是在技能模块中增加“依赖清单审查”步骤让 AI 主动检查依赖版本。业务逻辑漏洞。这类漏洞没有固定的代码模式比如“下单时没有校验库存”“退款金额可以超过订单金额”。AI 很难通过静态审查发现。解决办法是在审查指令中补充业务规则说明让 AI 结合规则判断。5.3 排查速查表现象可能原因排查方法AI 报告大量高危问题严重等级标准未定义或过宽检查技能模块中的分级标准调整阈值AI 只报告表面问题上下文不足或审查维度缺失补充调用链文件检查维度清单是否完整AI 漏掉明显漏洞数据流追踪中断或检查点未覆盖提供完整数据流增加对应检查点AI 报告的问题无法复现误报或代码版本不一致确认审查的代码版本人工验证问题AI 输出格式混乱输出模板未定义或指令不清晰在指令中明确输出格式要求5.4 独家避坑技巧技巧一先让 AI 做“数据流梳理”再做“安全审查”。分两步走第一步让 AI 输出数据流图文字描述即可第二步基于数据流做审查。这样 AI 的注意力更集中审查深度更好。技巧二用“反向提问”验证 AI 的判断。当 AI 报告某个问题是高危时追问一句“如果攻击者要利用这个问题需要满足什么条件”如果 AI 回答的条件在实际部署中不成立那这个问题可能被高估了。技巧三建立“已知问题库”。把团队历史上出现过的安全问题整理成清单作为技能模块的补充。AI 在审查时会优先匹配这些已知模式提高检出率。技巧四定期更新依赖漏洞数据。AI 的知识有截止日期依赖漏洞信息需要定期从外部数据源更新。我通常每个月更新一次依赖库的漏洞清单确保审查时能覆盖最新的 CVE。技巧五不要追求“零误报”。安全审查的目标是“不漏掉高危问题”而不是“不报任何误报”。适度的误报是可以接受的因为人工验证的成本远低于漏掉一个高危漏洞的代价。6. 技能模块的迭代与扩展方向security-audit-skill不是一成不变的。随着项目演进、技术栈变化、新的漏洞类型出现技能模块需要持续迭代。我目前的迭代节奏是每完成一轮审查记录误报和漏报的情况每月汇总一次调整检查点和判断依据每季度做一次大的版本更新增加新的审查维度或调整整体结构。扩展方向上我比较看好几个点一是增加“业务逻辑安全”维度覆盖那些无法通过代码模式识别的风险二是增加“配置安全”维度审查环境变量、配置文件、部署参数中的安全隐患三是与 CI/CD 流水线集成让安全审查成为代码合并前的自动步骤。不过这些扩展的前提是核心维度已经打磨稳定。我见过太多团队一开始就追求大而全结果每个维度都做得不深审查效果反而不如只做三四个核心维度。先把输入处理、认证授权、数据存储这三个维度做扎实再考虑扩展这是我踩过坑之后的建议。在实际项目中我通常会把security-audit-skill和通用代码审查技能分开使用。通用审查先跑一遍解决风格和可维护性问题安全审查再跑一遍专注安全维度。两轮审查的指令和上下文分开提供避免 AI 在两类问题之间来回切换影响审查深度。这个流程跑顺之后代码合并前的安全把关效率提升很明显尤其是对于多人协作、PR 频繁的项目效果比纯人工审查稳定得多。