security-audit

Installation
SKILL.md

安全审计(Security Audit)

CI/CD 拦确定性问题(依赖漏洞、硬编码密钥),本 skill 审需要理解力的问题(数据流追踪、业务逻辑安全)。 两者互补,不重复。


第一步:确定审计范围和深度

收到审计请求
  ├─ 快速扫描(单模块 / 局部改动 / 敏感模块修改后)
  │   选 1-2 个最相关的维度检查
  │   产出:终端输出结果,不生成报告
  └─ 完整审计(release 发版前 / 新服务首次上线 / 重大安全相关改动)
      5 个维度全量检查
      产出:docs/audits/YYYY-MM-DD-<服务名>-audit.md

范围识别

  1. 确定审计目标:哪些目录/模块/服务?用 AskUserQuestion 确认,不要猜
  2. 识别技术栈:检测 package.json / requirements.txt / pyproject.toml / tsconfig.json
  3. 识别敏感区域:优先审查以下目录和文件:
    • 路由定义、中间件(认证/鉴权相关)
    • 数据库操作层(ORM 调用、原生查询)
    • 用户输入处理(表单、API 参数解析)
    • 配置文件(CORS、安全头、环境变量引用)
    • 支付/订单/用户数据相关模块

第二步:逐维度审查

按以下 5 个维度逐一检查。每个维度都需要读代码,不是凭印象判断。

维度 1:注入防护

审查目标:用户可控的输入是否经过正确处理后才进入危险操作。

检查清单

注入类型 关注点 安全做法
SQL 注入 原生 SQL 拼接、ORM 的 raw query 参数化查询、预编译语句
命令注入 exec()child_processos.system()subprocess 避免拼接用户输入到命令,用参数数组
XSS innerHTMLdangerouslySetInnerHTML、模板中的未转义输出 输出转义、CSP 头、避免直接插入 HTML
路径遍历 用户输入拼接文件路径、../ 未过滤 路径规范化、白名单校验、path.resolve 后检查前缀
SSRF 用户输入作为 URL 发起服务端请求 URL 白名单、禁止内网地址、DNS rebinding 防护
模板注入 用户输入直接进入模板引擎渲染 避免动态模板编译、使用沙箱

审查方法

  1. 找到所有用户输入入口(路由参数、query、body、header、cookie)
  2. 追踪每个输入的数据流向——最终到了哪个危险函数?
  3. 中间有没有经过校验/转义/参数化处理?

维度 2:认证与授权

审查目标:确保每个需要保护的资源都有正确的认证和授权检查。

检查清单

检查项 关注点
认证覆盖 有没有接口"裸奔"——应该要登录但没加认证中间件?
授权粒度 用户 A 能不能通过改 ID 访问用户 B 的数据?(IDOR)
JWT/Session 密钥强度、过期时间、刷新机制、注销是否真的失效
CORS 策略 Access-Control-Allow-Origin 是否过于宽松(*)?credentials 模式下的 origin 检查
密码策略 密码是否 bcrypt/argon2 哈希存储、是否有强度要求
权限绕过 前端隐藏 ≠ 后端鉴权,检查是否只在前端做了权限判断

审查方法

  1. 列出所有路由/接口,标注哪些有认证中间件、哪些没有
  2. 找到"裸奔"接口,判断是否应该加认证
  3. 检查授权逻辑:当前用户只能操作自己的资源吗?

维度 3:敏感数据处理

审查目标:敏感数据在存储、传输、日志中是否得到正确保护。

检查清单

检查项 关注点
密码存储 是否用了 bcrypt/argon2?是否明文或 MD5/SHA1?
加密算法 是否使用了已知弱算法(DES、RC4、MD5 用于加密)
日志脱敏 日志里有没有打印密码、token、手机号、身份证号
错误信息 异常响应是否泄露了堆栈、SQL 语句、内部路径
数据传输 敏感 API 是否强制 HTTPS?cookie 是否设置 Secure 和 HttpOnly
前端存储 token 存 localStorage(可被 XSS 窃取)还是 httpOnly cookie?

审查方法

  1. 搜索密码/token 相关的存储和比对逻辑
  2. 搜索日志输出(console.loglogger.print),检查是否包含敏感字段
  3. 检查错误处理中间件,确认生产环境不返回堆栈信息

维度 4:配置安全

审查目标:安全相关配置是否合理,生产环境是否加固。

检查清单

检查项 关注点
安全响应头 X-Content-Type-Options、X-Frame-Options、Strict-Transport-Security、CSP
Debug 模式 生产环境是否关闭 debug/详细错误输出
默认凭证 是否存在默认密码、测试账号、admin/admin
速率限制 登录、注册、验证码等接口是否有 rate limit
文件上传 是否限制文件类型、大小?存储路径是否在 web 可访问目录外?
环境隔离 生产配置和开发配置是否分离?环境变量是否正确引用

维度 5:业务安全

审查目标:识别需要理解业务语义才能发现的安全风险。

检查清单

检查项 关注点
越权访问(IDOR) 修改请求中的 ID/参数能否访问他人数据
批量枚举 用户名/邮箱是否可被枚举(注册/登录/找回密码的不同返回)
竞态条件 余额扣减、库存扣减、优惠券核销是否有并发保护
逻辑绕过 支付金额是否可在前端篡改?流程步骤是否可跳过?
重放攻击 关键操作是否有幂等性保护或 nonce 机制
信息泄露 API 响应是否返回了多余字段(如其他用户的信息、内部 ID)

审查方法

  1. 站在攻击者视角思考:"如果我想偷数据/薅羊毛/搞破坏,我会怎么做?"
  2. 检查关键业务操作的参数校验和权限检查
  3. 关注"前端校验但后端没校验"的情况

第三步:风险分级

每个发现按以下标准分级:

等级 标准 处理要求
高危 可直接导致数据泄露、未授权访问、代码执行 必须修复后才能上线,给出具体修复代码
中危 存在利用条件但风险可控,或防御纵深不足 建议修复,给出修复方向
低危 最佳实践缺失,短期内风险较小 记录待改进,不阻断上线

分级原则:

  • 不确定时往高了分,宁可过度警惕不可遗漏
  • 但不要把所有发现都标高危——狼来了效应会降低警觉
  • 已有其他防御措施的可适当降级(如 XSS 风险但已有严格 CSP)

第四步:生成审计报告

完整审计时,生成报告到 docs/audits/YYYY-MM-DD-<服务名>-audit.md

# 安全审计报告:<服务名>

## 审计概览
- 审计日期:YYYY-MM-DD
- 审计范围:<目录/模块列表>
- 技术栈:<自动识别结果>
- 风险摘要:🔴 X 高危 / 🟡 X 中危 / 🟢 X 低危

## 审计结论

**✅ 通过** / **⚠️ 有条件通过(需修复高危后上线)** / **❌ 不通过**

## 详细发现

### 1. 注入防护
(发现 / 无风险)

### 2. 认证与授权
(发现 / 无风险)

### 3. 敏感数据处理
(发现 / 无风险)

### 4. 配置安全
(发现 / 无风险)

### 5. 业务安全
(发现 / 无风险)

## 修复清单

| # | 等级 | 维度 | 问题描述 | 文件位置 | 修复建议 |
|---|------|------|---------|---------|---------|

## 历史审计
- [上次审计](链接)(如有)

每个发现必须包含:

  • 具体代码位置(文件:行号)
  • 问题描述(是什么、为什么危险)
  • 攻击场景(攻击者怎么利用)
  • 修复建议(高危给代码,中危给方向)

第五步:修复与复查

  1. 高危问题:给出具体修复代码,协助用户当场修复
  2. 修复后复查:修复完成后,重新检查对应维度确认修复有效
  3. 报告更新:在修复清单中标记已修复项

与其他 skill/流程的衔接

CI/CD 安全流水线(自动化,确定性)
  ├─ pre-commit: gitleaks 拦截敏感信息
  └─ PR Check: 依赖漏洞 + 静态规则扫描
         ↓ 自动化通过后
security-audit(本 skill,AI 审查)
  ├─ task-finish 提示:涉及敏感模块时建议快速扫描
  └─ release 强制:发版前完整审计
         ↓ 审计通过
release — 发版

审计报告目录docs/audits/,命名格式 YYYY-MM-DD-<服务名>-audit.md


注意事项

  • 不要替代 CI/CD:依赖漏洞扫描(npm audit)、敏感信息 grep(gitleaks)是自动化流水线的事,本 skill 不重复做
  • 不要过度报告:只报告真实风险,不要为了显得全面把无关紧要的 warning 都列上
  • 理解业务再审:先用 code-walkthrough 或快速阅读理解业务逻辑,再做安全审查。脱离业务的安全审查是低效的
  • 攻击者思维:每个维度都要问"如果我是攻击者,我怎么利用这个?"。找不到攻击路径的问题不算高危
Related skills
Installs
2
GitHub Stars
102
First Seen
Apr 9, 2026