mcpField
S
security-audit

security-audit

github.com/aakash-dhar安全0160 次安装36 周前更新
代码仓库

关于 security-audit

security-audit 是用于指导代码安全审查的技能,覆盖常见应用和基础设施风险,并提供检查项与示例命令。内容包括凭据、注入、访问控制、数据暴露、依赖项及特定技术栈的风险。

主要功能

  1. 01密钥与凭据扫描
  2. 02注入和输入验证检查
  3. 03身份验证与授权审查
  4. 04数据暴露与加密检查
  5. 05依赖项和 HTTP 标头检查
  6. 06特定框架的审查指南

适用场景

  1. 01检查代码库是否泄露凭据
  2. 02审查 API 代码中的注入与访问控制问题
  3. 03检查应用配置和依赖项

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/aakash-dhar/claude-skills --skill security-audit

安装后在 Claude Code 中输入/security-audit确认已加载。

详细介绍

安全审计技能

审计代码安全性时,请遵循以下结构化流程。认真对待每项发现——单个漏洞就可能危及整个系统。

1. 密钥与凭据

扫描整个代码库,查找暴露的密钥:

  • 源代码中的硬编码 API 密钥、令牌、密码
  • 提交到 Git 的配置文件中的密钥(.env、config.json、settings.py)
  • 日志中的密钥——在 console.log、logger.info 等输出的敏感数据
  • 错误消息中的密钥——泄露内部信息的堆栈跟踪或错误响应
  • 注释中的密钥——遗留在 TODO 或已注释代码中的旧凭据
  • Git 历史记录中的密钥——检查密钥是否曾被提交后又删除(仍保留在历史记录中)

检查命令:

# Search for common secret patterns
grep -rn "password\|secret\|api_key\|apikey\|token\|private_key\|AWS_SECRET\|DATABASE_URL" --include="*.ts" --include="*.js" --include="*.py" --include="*.env" --include="*.json" --include="*.yaml" --include="*.yml" .

# Check for .env files committed
git ls-files | grep -i "\.env"

# Check git history for secrets
git log --all --diff-filter=D -- "*.env" "*.pem" "*.key"

验证:

  • 是否配置了 .gitignore,包含 .env、.pem、.key、*.p12?
  • 密钥是否通过环境变量或保险库加载(而非从文件加载)?
  • 是否有 .env.example,其中使用的是占位值(而非真实密钥)?

2. 注入攻击

SQL 注入
// 🔴 VULNERABLE — string concatenation in query
const user = await db.query(`SELECT * FROM users WHERE id = '${req.params.id}'`);

// ✅ SAFE — parameterized query
const user = await db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);
NoSQL 注入
// 🔴 VULNERABLE — user input directly in query object
const user = await User.find({ username: req.body.username });

// ✅ SAFE — explicitly cast to string
const user = await User.find({ username: String(req.body.username) });
命令注入
// 🔴 VULNERABLE — user input in shell command
exec(`convert ${req.body.filename} output.png`);

// ✅ SAFE — use execFile with arguments array
execFile('convert', [sanitizedFilename, 'output.png']);
XSS(跨站脚本攻击)
// 🔴 VULNERABLE — unsanitized HTML rendering
element.innerHTML = userInput;
// React: dangerouslySetInnerHTML={{ __html: userInput }}

// ✅ SAFE — use textContent or sanitize
element.textContent = userInput;
// React: use DOMPurify.sanitize() before dangerouslySetInnerHTML
路径遍历
// 🔴 VULNERABLE — user controls file path
const file = fs.readFileSync(`./uploads/${req.params.filename}`);

// ✅ SAFE — resolve and validate path stays within allowed directory
const safePath = path.resolve('./uploads', req.params.filename);
if (!safePath.startsWith(path.resolve('./uploads'))) throw new Error('Invalid path');
模板注入
  • 检查是否将用户输入直接传递给模板引擎(Jinja2、EJS、Handlebars)
  • 验证是否已启用自动转义

3. 身份验证与授权

身份验证缺陷
  • 密码要求过弱——没有最小长度、复杂度要求或泄露检查
  • 登录端点缺少速率限制(存在暴力破解风险)
  • 多次登录失败后未锁定账户
  • 密码存储不安全——明文、MD5、SHA1(使用适当成本参数的 bcrypt/argon2)
  • 敏感操作缺少 MFA
  • 会话令牌出现在 URL 中——令牌应放在请求头或 httpOnly Cookie 中
  • 会话没有过期机制——令牌永不过期
授权缺陷
  • 缺少授权检查——未验证用户权限即可访问端点
  • IDOR(不安全的直接对象引用)——通过更改 ID 访问其他用户的数据
  • 权限提升——普通用户可以访问管理员端点
  • 缺少资源所有权检查——用户 A 可以修改用户 B 的数据
// 🔴 VULNERABLE — IDOR: no ownership check
app.get('/api/orders/:id', async (req, res) => {
  const order = await Order.findById(req.params.id);
  res.json(order);
});

// ✅ SAFE — verify ownership
app.get('/api/orders/:id', async (req, res) => {
  const order = await Order.findById(req.params.id);
  if (order.userId !== req.user.id) return res.status(403).json({ error: 'Forbidden' });
  res.json(order);
});

4. 数据泄露

  • API 响应中的敏感数据——返回密码、令牌、SSN、完整信用卡号
  • 生产环境中的详细错误消息——堆栈跟踪、数据库详细信息、内部路径
  • 缺少字段筛选——返回整个数据库对象,而非指定字段
  • 客户端存储中的敏感数据——令牌存放在 localStorage 中(应使用 httpOnly Cookie)
  • 日志中的 PII——记录姓名、电子邮件、IP,且未进行脱敏
  • 缺少数据加密——敏感数据以未加密形式静态存储
  • CORS 配置错误——在需要身份验证的端点上使用 Access-Control-Allow-Origin: *
// 🔴 VULNERABLE — leaking sensitive fields
res.json(user);

// ✅ SAFE — explicit field selection
res.json({
  id: user.id,
  name: user.name,
  email: user.email,
});

5. 输入验证

  • 缺少验证——未检查请求正文、参数、查询字符串
  • 类型混淆——预期为数字,却接受字符串
  • 缺少长度限制——无界输入可能导致 DoS
  • 缺少文件上传验证——未检查文件类型、大小或内容
  • 正则表达式 DoS(ReDoS)——恶意输入导致灾难性回溯
  • 缺少内容类型验证——接受意外的内容类型

验证:

  • 是否使用了验证库(Zod、Joi、class-validator、Pydantic)?
  • 是否所有 API 端点都在处理输入前进行验证?
  • 文件上传是否按类型和大小进行限制,并经过恶意软件扫描?

6. 依赖项

运行以下检查:

# Node.js
npm audit
# or
npx better-npm-audit audit

# Python
pip audit
# or
safety check

# Check for outdated packages
npm outdated
pip list --outdated

检查以下内容:

  • 依赖项中是否存在已知 CVE
  • 是否存在带有已知漏洞的过时软件包
  • 已弃用的软件包——两年或更久没有更新
  • 拼写仿冒风险——确认软件包名称正确
  • 权限过多——软件包请求了超出所需范围的访问权限
  • 是否存在锁定文件——已提交 package-lock.json 或 yarn.lock

7. HTTP 安全标头

检查是否设置了以下标头:

  • Content-Security-Policy — 防止 XSS 和数据注入
  • Strict-Transport-Security — 强制使用 HTTPS
  • X-Content-Type-Options: nosniff — 防止 MIME 类型嗅探
  • X-Frame-Options: DENY — 防止点击劫持
  • Referrer-Policy — 控制引荐来源信息
  • Permissions-Policy — 限制浏览器功能
# Check response headers
curl -I https://your-app.com

8. 密码学

  • 弱哈希算法 — 使用 MD5 或 SHA1 存储密码(应使用 bcrypt、scrypt 或 argon2)
  • 弱加密算法 — 使用 DES、RC4、ECB 模式(应使用 AES-256-GCM)
  • 硬编码的加密密钥 — 密钥应存储在环境变量或密钥库中
  • 缺少 TLS — 敏感数据通过 HTTP 连接传输
  • 弱 JWT — 使用 alg: none,或使用短密钥的 HS256
  • 可预测的随机值 — 使用 Math.random() 生成令牌(应使用 crypto.randomBytes)
// 🔴 VULNERABLE — predictable token
const token = Math.random().toString(36);

// ✅ SAFE — cryptographically secure
const token = crypto.randomBytes(32).toString('hex');

9. 基础设施与配置

  • 在生产环境中启用调试模式 — 暴露详细错误、堆栈跟踪和调试端点
  • 默认凭据 — admin/admin、root/root 等默认凭据仍可使用
  • 开放了不必要的端口 — 数据库端口暴露在互联网上
  • 缺少速率限制 — 无法防范 DoS
  • 缺少请求大小限制 — 大型负载可能导致内存耗尽
  • 不安全的 CORS 配置 — 已认证的端点允许通配符来源
  • 缺少 CSRF 防护 — 更改状态的端点未使用 CSRF 令牌

10. 特定技术栈检查

Node.js / Express
  • 确认已安装并配置 helmet 中间件
  • 检查 express.json() 是否设置了大小限制:express.json({ limit: '10kb' })
  • 确认 Cookie 设置正确:httpOnly、secure、sameSite
  • 检查合并对象时是否存在原型污染问题(lodash.merge、将用户输入传给 Object.assign)
  • 确认 child_process 调用会清理所有输入
  • 检查是否对身份验证端点应用了 express-rate-limit
  • 检查事件发射器是否存在内存泄漏(缺少 removeListener)
  • 确认没有将用户输入传给 eval()、Function() 或 vm.runInNewContext()
Python / Django
  • 确认生产环境设置中 DEBUG = False
  • 检查 ALLOWED_HOSTS 是否不是 ['*']
  • 确认已启用 CSRF 中间件
  • 检查是否存在未使用参数化查询的原始 SQL 查询
  • 确认 SECRET_KEY 从环境中读取,而非硬编码
  • 检查是否对用户输入进行 pickle 反序列化(存在 RCE 风险)
  • 确认 django-cors-headers 配置了特定来源
  • 检查所有受保护的视图是否都使用了 @login_required 或权限类
  • 检查是否存在不安全的 YAML 加载(使用 yaml.load() 时未设置 Loader=SafeLoader)
  • 确认生产环境中 SECURE_SSL_REDIRECT、SESSION_COOKIE_SECURE、CSRF_COOKIE_SECURE 均为 True
Python / Flask
  • 确认 app.secret_key 未被硬编码
  • 检查受保护路由是否缺少 @login_required 装饰器
  • 确认已启用 Jinja2 自动转义(Flask 默认启用,但需检查自定义模板)
  • 检查是否使用 flask-talisman 或类似工具设置安全标头
  • 确认对身份验证端点和敏感端点应用了 flask-limiter
  • 检查是否存在不安全的文件上传(缺少 werkzeug 的 secure_filename())
React / Next.js
  • 检查是否将未经清理的输入传给 dangerouslySetInnerHTML
  • 确认没有将令牌存储在 localStorage 中(应使用 httpOnly Cookie)
  • 检查客户端代码或代码包中是否包含敏感数据
  • 确认环境变量仅对非敏感值使用 NEXT_PUBLIC_ 前缀
  • 检查 URL 参数中是否存在开放重定向
  • 确认 API 路由具有适当的身份验证中间件
  • 检查 Server Actions 是否验证输入并检查授权
  • 检查 getServerSideProps 中是否有泄露到 pageProps 的敏感数据
  • 确认 next.config.js 已配置适当的安全标头
  • 检查生产环境中是否暴露了源映射
Vue / Nuxt
  • 检查 v-html 是否使用了未经清理的用户输入
  • 确认没有将令牌存储在 localStorage 中
  • 检查 nuxt.config 是否暴露了 runtime config 中的密钥
  • 确认服务端中间件包含身份验证检查
  • 检查是否通过 useAsyncData 或 useFetch 将敏感数据从服务端泄露到客户端
Ruby on Rails
  • 确认生产环境中设置了 config.force_ssl = true
  • 检查用户提供的内容是否使用了 html_safe 或 raw
  • 确认已启用 protect_from_forgery
  • 检查是否存在批量赋值漏洞(缺少 strong_parameters)
  • 确认 has_secure_password 使用了 bcrypt
  • 检查是否使用用户输入调用不安全的 send() 或 constantize()
  • 确认 config.filter_parameters 包含敏感字段
Go
  • 检查查询中使用的 fmt.Sprintf 是否存在 SQL 注入风险(应使用参数化查询)
  • 确认 TLS 配置使用的最低版本为 TLS 1.2
  • 检查 http.ServeFile 或 os.Open 是否存在路径遍历风险
  • 确认错误处理得当(错误响应中不包含敏感数据)
  • 检查共享状态是否存在竞态条件(缺少互斥锁)
  • 确认安全敏感值使用 crypto/rand,而非 math/rand
  • 检查是否存在可能导致 panic 的未检查类型断言
Java / Spring Boot
  • 确认已配置 Spring Security,且敏感端点未使用 permitAll()
  • 检查 @Query 注解中通过字符串拼接构造的查询是否存在 SQL 注入风险
  • 确认已启用 CSRF 防护(Spring Security 默认启用)
  • 检查是否存在反序列化漏洞(Jackson、Java 序列化)
  • 确认请求体参数上存在 @Valid 注解
  • 检查 application.properties 或 application.yml 中是否硬编码了凭据
  • 确认 actuator 端点受到保护,且未向公众开放
  • 检查依赖中是否存在 Log4j/Log4Shell 漏洞
PHP / Laravel
  • 确认生产环境 .env 中设置了 APP_DEBUG=false
  • 检查原始 SQL 查询是否未使用参数绑定
  • 确认 CSRF 中间件已应用于所有 POST/PUT/DELETE 路由
  • 检查 eval()、exec()、system() 是否使用了用户输入
  • 确认文件上传使用了验证规则(MIME 类型、最大大小)
  • 检查敏感路由是否受到 Auth::check() 或中间件守卫的保护
  • 确认通过 $fillable 或 $guarded 防护批量赋值
  • 检查是否使用 {!! !!} 不安全地渲染用户输入的 Blade 内容
移动端(React Native / Flutter)
  • 检查是否在 AsyncStorage/SharedPreferences 中存储了敏感数据(应使用加密存储)
  • 确认 API 密钥未嵌入应用程序包中
  • 检查敏感 API 调用是否启用了证书固定
  • 确认深层链接处理程序在导航前会验证输入
  • 检查应用日志中是否包含敏感数据(可通过 adb logcat / Console.app 查看)
  • 确认生物识别身份验证已在服务端正确验证
  • 检查 WebView 配置是否不安全(对不可信内容启用了 JavaScript)
支付安全
  • 确认符合 PCI DSS 要求
  • 检查是否从未存储或记录完整的信用卡号
  • 确认支付处理使用了令牌化
  • 检查 webhook 端点是否验证签名
  • 确认退款端点具备适当的授权和速率限制
  • 检查支付金额是否在服务端验证(而非信任客户端提供的金额)
  • 确认支付确认页面不会在 URL 中暴露交易详情
  • 检查支付处理中是否存在竞态条件(可能导致重复扣款)
AWS / 云基础设施
  • 检查 IAM 策略是否权限过宽("Action": "*"、"Resource": "*")
  • 确认 S3 存储桶未公开访问
  • 检查 RDS 实例或 EBS 卷是否未加密
  • 确认安全组未允许从 0.0.0.0/0 访问敏感端口
  • 检查是否硬编码了 AWS 凭据(应改用 IAM 角色)
  • 确认已启用 CloudTrail 日志记录
  • 检查是否存在运行敏感服务且可公开访问的 EC2 实例
  • 确认密钥存储在 AWS Secrets Manager 或 Parameter Store 中
Docker / 容器
  • 检查是否有以 root 身份运行的容器
  • 确认基础镜像来自可信来源,并固定到特定版本
  • 检查 Docker 镜像中是否包含密钥(使用构建密钥或运行时环境变量)
  • 确认 .dockerignore 排除了 .env、.git、node_modules
  • 检查生产镜像中是否安装了不必要的软件包
  • 确认已配置健康检查
  • 检查是否暴露了不应公开的端口

输出格式

对于发现的每个漏洞:

[严重程度] 类别 — 文件:行号

  • 漏洞:问题是什么
  • 风险:攻击者可能利用此问题做什么
  • 验证方法:如何利用该问题(供内部团队了解)
  • 修复方法:解决问题所需的确切代码更改
  • 参考资料:适用时提供 CWE 或 OWASP 链接
// vulnerable code
...

// fixed code
...

严重程度级别:

  • 🔴 严重 — 可被主动利用。可能导致数据泄露、RCE 或系统完全失陷。立即修复。
  • 🟠 高 — 需要一定努力即可利用。可能导致重大数据泄露或权限提升。下次部署前修复。
  • 🟡 中 — 需要特定条件才能利用。在当前迭代中修复。
  • 🟢 低 — 轻微问题或纵深防御改进。有空时修复。

总结

每次审计结束时都要包含:

  1. 风险评级 — 整体安全状况(严重 / 高 / 中 / 低风险)
  2. 严重问题数量 — 需要立即处理的问题数量
  3. 最危险的 3 个问题 — 按可利用性和影响程度排序
  4. 快速改进项 — 用时少于 30 分钟且能显著降低风险的修复
  5. 建议 — 长期改进措施(WAF、安全标头、在 CI 中扫描依赖项等)
  6. 做得好的方面 — 已落实且应继续保持的安全实践

评论

支持 Markdown