ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

从零构建Security Audit Skill:把安全审计经验封装成Agent技能包

从零构建Security Audit Skill:把安全审计经验封装成Agent技能包 很多人看到security-audit-skill这个标题第一反应是这又是一个安全审计工具还是某个新出的插件实际上这是最近大模型Agent生态里非常火的一类东西——把专业的安全审计能力封装成一个AI可以稳定调用的技能包Skill。我花了大概两周时间把平时做Web渗透测试、代码审计、配置检查的经验整理成了一个可复用的Security Audit Skill整个过程踩了不少坑也总结出了一些方法论。这篇文章就详细说说我是怎么设计、实现并验证这个Skill的。先解释下背景。Skill在Agent生态里可以理解成给AI的一份详细操作手册工具集。你光告诉AI帮我做安全审计它可能只会泛泛而谈但如果你给它一个定义良好的Skill里面有明确的检查项、规则库、工具调用方式、输出模板它就能像一位初级安全工程师一样按流程完成检测并输出结构化报告。这正好解决了两个痛点一是安全审计本身高度依赖经验和流程新手很难直接上手二是大模型对话式交互的不确定性太高没有Skill约束AI很容易输出正确的废话。这篇文章不是纯理论而是我从零开始构建Security Audit Skill的完整记录。适合三类人看想把自己安全经验产品化的安全工程师、在做Agent开发但不知道Skill怎么落地的开发者、以及刚接触AI编程工具但想给它配专业技能的进阶用户。1. 为什么要把安全审计封装成Skill1.1 安全审计到底在审什么在动手写Skill之前我得先想明白一件事我日常做的安全审计核心工作到底是什么拆解下来其实就几大类信息收集域名、端口、指纹、漏洞检测注入、XSS、SSRF、越权等、配置核查CORS、安全头、认证策略、依赖检查第三方组件版本漏洞、敏感信息泄露排查硬编码密钥、云凭证、源码泄露。这些工作的共同点是什么流程固定、规则明确、重复性高。比如检查CORS配置就是看响应头里有没有Access-Control-Allow-Origin以及它是不是反射了Origin检查SQL注入就是找用户输入点是否未经处理就拼进SQL语句。这类工作完全可以标准化成检查清单而这正好是Skill最擅长的形式。我见过很多安全团队想引入AI辅助审计但效果不好。最常见的失败模式是直接让大模型帮我审计这段代码结果模型给出一个非常泛的结论——建议加强输入验证注意SQL注入风险——没有任何可操作性。问题不在于模型能力而在于没有给它一个清晰的审计框架。Skill的价值就在这里它把碎片化的审计经验变成了一套模型可以严格遵循的SOP。1.2 Skill和Agent、工作流到底是什么关系顺着前面的热搜词说很多人搞不清Skill和Agent的区别。我自己的理解是Agent是执行的主体负责理解目标、拆解任务、调用工具Skill则是Agent可以加载的能力模块相当于给Agent换了一套职业技能包。一个Agent可以装多个Skill比如一个编码Agent可以同时拥有前端最佳实践Skill和安全审计Skill。Skill本质上是Prompt工程工具配置知识库的组合体通常是目录结构里放一个SKILL.md描述技能用途和用法再配若干个references参考资料和scripts可执行脚本。用生活类比来说Agent是一个新入职的实习生聪明但没经验Skill就是岗位培训手册和工具包。你给它一本优秀的手册它就能按流程干活不给手册它就靠临场发挥结果完全不可控。Security Audit Skill就是给AI实习生的一份安全岗位手册里面写清楚每一步检查什么、怎么查、什么结果算漏洞、什么结果算误报。1.3 这件事的实际场景价值为什么要把安全审计单独做成一个Skill而不是直接写在System Prompt里两个原因可维护性和可复用性。可维护性方面安全知识更新非常快。今天新增了一个CVE明天某个框架出了一个新特性导致新的攻击面。如果这些知识全堆在系统提示词里每次更新都要改一遍主流程而且提示词会越来越长模型注意力会被稀释。做成Skill之后更新一个markdown文件或脚本就够了完全不碰主流程。可复用性方面同一个Skill可以挂到不同的Agent上。我在Claude Code里挂了它在自研的Agent框架里也挂了它后面准备在Codex里也挂一份。一次编写多处使用这才是Skill的真正意义。2. 设计审计知识体系——Skill内容的地基2.1 把OWASP Top 10变成可执行的检查项Skill的核心是知识不是代码。我开始动手的时候第一步不是写SKILL.md而是先整理审计知识体系。最省事也最权威的起点就是OWASP Top 10——但注意不能直接把Top 10整段复制进来那样模型会读了很多但不知道怎么用。我的做法是把每个风险类别转译成输入 - 检查动作 - 判定条件 - 输出结果这样的结构。举个例子对于注入这一项我定义的不是检查是否存在SQL注入这种空泛描述而是具体的检测指令检查所有数据库查询语句。如果用户输入直接拼接到SQL字符串中标记为高风险如果使用了参数化查询标记为安全如果使用白名单校验但未使用参数化标记为中风险并提示进一步人工确认。这种转译工作非常关键。大模型虽然知识量大但在执行任务时它更擅长按照明确指令去推理而不是自己从长篇原理中提炼出检查逻辑。可以说Skill的水平很大程度上取决于知识转译的质量而不是知识库的体量。我最后形成的知识体系覆盖了八大类注入类、认证与会话类、敏感数据泄露类、XML外部实体与SSRF类、安全配置类、XSS与前端安全类、不安全的反序列化类、日志与监控类。每一类底下都挂了3到8个具体检查项。2.2 安全审计知识库要包含哪些素材我复盘了一下最终沉淀进Skill的知识素材可以分成四层分层越多审计越准第一层是检查项清单也就是前面说的转译后的检查规则。这是主体大概占了知识库的60%。第二层是常见漏洞案例我会放一些经典的漏洞代码片段和修复后的对比比如登录接口的越权漏洞、S3桶的公共读配置。给模型看坏例子和好例子对比能显著提高检出准确率。第三层是命令与工具参考告诉AI在什么场景下应该调用什么安全工具比如端口扫描用什么、目录爆破用什么、依赖检查用什么。第四层是报告模板规定输出格式避免AI自由发挥。这四层内容我用Markdown文件分开存放放在references目录下。这样做的另一个好处是模型在审计时不需要一次性读完全部知识而是可以根据SKILL.md里的指引按需去检索对应的reference文件。既省上下文窗口又提高了针对性。2.3 知识的更新机制说实话第一次整理知识库花了三个晚上。但我没指望它一次成型——安全知识是持续变化的Skill需要维护。我现在的维护机制很简单每半个月过一遍安全资讯把新增的漏洞类型和检测规则追加到对应的reference文件里每次做完一次实际项目审计我会把项目中遇到的特殊案例也补充进去。这里我要特别强调一个原则宁可规则少而精不要多而滥。我曾经为了让Skill看起来全面塞进去大量过时或低价值的检查项结果审计报告里出现了一堆无意义的提醒比如建议使用HTTPS这种正确的废话。后来我把那些无法被明确判定的规则全部下线准确率反而明显提升了。3. 实现一个可落地的Security Audit Skill3.1 Skill目录结构设计知识体系理清楚之后就开始搭Skill的骨架了。我参考了当下主流Agent Skill的规范设计了这样一个目录结构security-audit-skill/ ├── SKILL.md ├── assets/ │ ├── icons/ │ └── examples/ ├── references/ │ ├── owasp-top10-checklist.md │ ├── common-vulnerabilities-cases.md │ ├── tool-commands-reference.md │ └── report-template.md ├── scripts/ │ ├── dependency-check.py │ ├── secret-scan.py │ ├── cors-checker.py │ └── format_report.py └── config/ └── severity.yaml解释一下每个目录的用途。SKILL.md是入口文件Agent会先读它来决定如何使用整个技能。references存放前面说的四层知识素材用Markdown写方便AI直接理解。scripts目录放真正的检测脚本这些脚本不是给人类用的而是给AI调用来获取精确检测结果的。config里存放等级定义和阈值配置方便统一调整。这个结构不是拍脑袋定的而是参考了目前比较成熟的Agent Skill项目实践。核心思想是让描述性的知识和可执行的代码分离。描述性知识给AI理解用可执行代码给AI调用用两者通过SKILL.md衔接。3.2 SKILL.md的核心写作方法SKILL.md是整个Skill的心脏它决定了AI会不会用、能不能用好你提供的知识和工具。一开始我写得很简短只有三四行描述结果AI执行起来完全失控要么不做检查直接给结论要么检查了但不看references里的规则。后来我重写了SKILL.md加入了四个关键部分技能描述、适用场景、执行步骤、输出要求。先看一个简化的SKILL.md骨架# Security Audit Skill ## Description Perform security audit on source code or live web applications, covering injection, auth, misconfiguration, sensitive data exposure, and dependency risks. Follow a structured checklist and output a risk-ranked report. ## When To Use - User requests security review of code files or code snippets - User requests vulnerability scanning of a web app or API endpoint - User asks for dependency risk assessment ## Steps 1. Confirm the audit scope: code or live target. 2. Load the appropriate reference file from references/. 3. Run automated scripts from scripts/ if the local environment permits. 4. Enumerate findings with severity, evidence, and remediation. 5. Re-check findings for false positives before generating the final report. ## Output Format - Summary table: finding, severity, confidence, status - Evidence: exact location (file/line/URL), with code snippet - Remediation: concrete, actionable fix - Risk level color: high / medium / low关键在哪在于When To Use这段。很多人写SKILL.md只写能做什么忽略什么时候该用、什么时候不该用导致Agent经常误用。我加上了一个明确规则只有在用户要求审计代码或Web应用时才加载此技能如果用户只是泛泛问什么是SQL注入应该直接用普通对话回答不调用Skill。3.3 自动化检测脚本的设计Skill里的scripts是提升审计精度的核心武器。大模型靠读能发现一部分问题但很多问题需要精确检测比如正则匹配密钥、比对依赖版本、检查HTTP响应头。这部分我写了四个脚本逐个说下设计思路。dependency-check.py用来检查依赖组件版本。核心逻辑很简单解析requirements.txt、package.json等依赖清单文件提取组件名和版本号与本地维护的一个漏洞版本库比对匹配到就报告漏洞编号和风险说明。为什么这个脚本有价值因为CVE版本库信息相对稳定、规则明确用代码查比让AI凭记忆判断可靠得多。secret-scan.py用来扫描硬编码的敏感信息。原理就是一堆正则规则匹配AWS Access KeyAKIA开头的字符串、匹配私钥块-----BEGIN RSA PRIVATE KEY-----、匹配常见的密码赋值语句。这里有个重要的设计决策脚本只负责发现候选线索至于这些线索是不是真的密钥、有没有实际泄露出现在代码里脚本不做判定而是把上下文一起交给AI让AI结合业务逻辑做二次判断。cors-checker.py用于检测CORS配置。如果我审计的是一个线上站点这个脚本会向目标发送带自定义Origin的请求观察响应头Access-Control-Allow-Origin是否反射了Origin如果反射了则说明CORS配置存在风险。如果审计的是代码这个脚本就退化为检查后端代码里的CORS中间件配置。format_report.py负责把检测结果整理成统一的报告格式。我规定输出必须是一个Markdown表格加若干详情段落表格列出发现、危害等级、置信度、修复建议这样无论是人看还是后续交给其他Agent处理都方便。这里顺带提一下Scripts脚本化的一个重要好处可复现。同一个检测命令AI每次执行的结果一致不依赖模型心情。而纯靠模型判断的东西同样的输入换一次对话可能就有不同结论这在安全审计里是不可接受的。3.4 检测规则的配置与等级定义前面提到config/severity.yaml我单独说说这个文件的作用。它定义了每个检查项的等级和阈值。我按严重程度把问题分成四级Critical可直接导致数据泄露或系统被控、High可被利用但需要一定条件、Medium需要特殊场景或与其他漏洞组合利用、Low最佳实践问题不直接造成危害。等级定义的好处是让AI给出结论时有统一标准。实际使用中我发现如果不提前定义清楚AI经常把中风险的问题标成高危造成误报恐慌。比如使用HTTP协议这事儿如果没有上下文我不允许AI直接标为中风险——只有在涉及登录、支付等敏感场景时才可以升级为高危。同时我在severity.yaml里还设了一些审计的豁免规则。比如某个目录注明是测试代码或者某段代码是生成器自动生成的这类代码可以适当降低审计优先级。这些规则如果不提前写清楚AI会在所有代码上花同样的精力效率极低。4. 实操验证把Skill跑起来看看效果4.1 用真实漏洞样本做回归测试Skill写完不是终点验证才是。我找了一个内部测试用的Web应用里面故意埋了6个已知漏洞一个SQL注入登录接口、一个SSRFURL抓取功能、一个越权订单查看接口、一个硬编码密钥、一个CORS配置错误、一个过期的依赖组件。我先用裸模型不加载Skill做了一轮审计让它检查这个应用的安全性。结果是发现了一个SQL注入和硬编码密钥其余四个全miss掉了而且唯一的SQL注入判断还是因为代码里注释写得太明显。然后我加载Security Audit Skill重跑一轮结果是六个问题全部命中还额外发现了一个我在埋漏洞时都没注意到的小问题——某个API的响应头泄露了服务器版本信息。这个对比足以说明Skill的价值同样的模型加个Skill审计能力直接上了一个台阶。原因在于裸模型是凭直觉审计而带Skill的模型是按清单审计——它知道该去哪里看、该看什么、什么特征代表什么问题。4.2 误报率压测与阈值调整检出能力提升之后下一个问题是误报率。我在一个没有故意埋漏洞的常规项目代码上跑了Skill结果第一次运行出了8条告警。逐条人工复核后有3条是误报一条把普通的字符串拼接当成SQL注入候选了、一条把测试环境配置当成了生产环境密钥、一条把自定义加密的字段当成了硬编码密码。这三条误报给了我两个教训。第一Skill里必须有上下文确认环节——检测脚本输出候选线索后AI不能直接采信必须结合文件上下文确认它是否确实处于危险位置。比如字符串拼接要确认拼接进的是SQL语句还是日志语句。第二等级配置要保守对置信度不高的发现要么标记为待确认要么降为中低风险不能一律标成高危。针对误报我给SKILL.md加了一条强制指令所有由自动化脚本发现的候选问题在写入最终报告前必须经过二次验证验证方法包括重读代码上下文、查看配置所在环境标签、确认数据流是否真的可以从用户侧触发。加了这个流程后误报率从38%降到了12%左右剩下的12%也大多是无法完全排除但需要人工确认的合理提示。4.3 与人工复核流程的衔接Skill再强也不能替代安全工程师做最终裁决。这一点我一再跟团队强调。我把Skill定位成高强度的辅助,它负责把审计覆盖面铺开、把可疑点找全、把报告初稿写好但最终每条漏洞的真伪、危害等级的判定、修复方案的确定必须由人来完成。实际操作中我建议的处理流程是这样的Skill输出报告后人工先看Critical和High等级的问题逐个验证可复现性Medium等级的问题按批次抽查Low等级的问题直接附加到待办清单不花太多时间。同时人工复核的结果要反哺给Skill——凡是被人工判定为误报的我都在references里记一条反面案例下次AI再遇到类似情况就知道绕开。5. 常见问题与排查技巧实录5.1 模型不按Skill流程执行怎么办我在实际使用中碰到的第一个大问题就是模型加载了Skill但不遵守里面的步骤。明明SKILL.md里写了先加载reference文件再开始检测它偏不直接凭记忆输出了一堆通用安全建议。后来我查了一下发现原因是SKILL.md里我把执行步骤放在了Description后面模型读到Description就以为自己理解了整个任务后面的Steps根本没细看。解决方法是把SKILL.md的结构顺序调整一下把Steps提到前面并且在Description里加一句你必须在开始输出前严格按照Steps部分列出的顺序完成所有步骤。还有一个技巧是给每个步骤编号在SKILL.md里明确说每一步输出的结果都要标注对应的步骤编号。这能有效约束模型的行为流程。5.2 上下文窗口被references撑爆了刚开始把我的全部安全审计知识都放在references里的时候出现了另一个问题模型在处理一个任务时把references下所有文件全初始化进上下文了结果还没开始审计上下文就已经用掉了一大半后面的推理质量严重下降。排查后确认问题出在SKILL.md里我写了一句加载references目录下的所有文件模型就真的全加载了。正确的做法是在SKILL.md里明确说明每个文件的使用条件比如仅在审计依赖时读取dependency-security.md仅在检测密钥泄露时读取secret-scan-rules.md。这样模型就会按需加载上下文占用立刻降了下来。5.3 输出格式不稳定还有一阵子特别头疼的问题就是同样一个Skill换不同的会话执行报告的格式经常不一致。有时候是表格有时候是列表有时候有证据有时候只有建议。对于需要继续喂给下游流程的报告来说格式不稳定简直致命。这个问题最终靠两件事解决。第一我在SKILL.md的输出格式部分给出了一个极其具体的模板连列名都写死了甚至给了一个迷你示例。第二我写了一个format_report.py脚本AI把发现的原始JSON结果交给脚本由脚本统一生成最终Markdown报告。也就是说从让AI格式化变成了让AI填数据、脚本管格式稳定性大大提升。5.4 Skill的版本迭代与知识更新怎么管理最后说一下版本管理。Skill不是一个一次性的东西它会持续演进。我现在的做法是每次重要改动都记一条CHANGELOG并且用语义化版本号v1.0.0、v1.1.0标记。大版本代表结构性的变化小版本代表新增检查项补丁版本代表修bug或调阈值。这个习惯在一次事故中帮了大忙有一次我改了references里的一个规则导致一批本应发现的问题全部漏报团队查了半天没头绪。最后通过对比CHANGELOG才发现是某个新增规则覆盖了旧规则。从那之后我形成了一个铁律Skill的每一处改动都要有记录必须能回滚。最后再分享一个使用心得这个Security Audit Skill我已经用了小半年最大的感悟是做Skill不是在训练AI而是在结构化自己的经验。把安全审计这件事拆成清单、规则、脚本和模板的过程本身就是一次对自身知识体系的梳理和升级。哪怕你最后不用在任何Agent上光是把审计流程这样整理一遍对团队的新人培训、对审计质量的标准化都有非常大的帮助。现在这个Skill已经支持我们团队完成日常的代码安全巡检、上线前安全评估、第三方依赖风险排查等工作。每次跑完一个项目我都会花几分钟看看有没有新的漏报或误报案例顺手补充进references。这一步坚持下来Skill会越用越顺手最终变成你团队里最勤快的初级安全工程师。
返回列表