安全基础审查 security-fundamentals

这个技能用于审查软件安全基础,涵盖OWASP Top 10、输入验证、身份认证、授权等关键方面。适用于开发者在构建登录系统、处理用户输入、管理API密钥和JWT令牌时的安全审查。关键词:安全审查、OWASP、输入验证、认证、授权、密码存储、API安全、网络安全。

安全审计 0 次安装 0 次浏览 更新于 3/8/2026

name: security-fundamentals description: 审查安全,包括OWASP Top 10、输入验证、认证。当初级开发者构建登录、认证、存储密码、处理用户输入、API密钥、JWT令牌,或询问“这安全吗”时使用。

安全基础审查

“安全不是功能。它是基础。建在沙子上,房子会倒塌。”

何时应用

在审查时激活此技能:

  • 认证/登录流程
  • 授权检查
  • 用户输入处理
  • 数据库查询
  • 文件上传
  • API端点
  • 响应中的数据暴露

审查清单

输入验证(绝不信任客户端)

  • [ ] 所有输入已验证:每个用户输入在使用前都检查了吗?
  • [ ] 服务器端验证:验证在服务器上完成,不仅客户端吗?
  • [ ] 类型检查:强制执行预期类型吗?
  • [ ] 长度限制:字符串长度有界限吗?
  • [ ] 白名单优于黑名单:明确定义允许的值吗?

认证

  • [ ] 密码哈希:密码是否哈希(bcrypt、argon2),而不是加密?
  • [ ] 无明文秘密:秘密在环境变量中,而不是代码中吗?
  • [ ] 令牌过期:JWT/会话有合理的过期时间吗?
  • [ ] 安全传输:强制执行HTTPS吗?

授权

  • [ ] 所有权检查:用户只能访问他们自己的数据吗?
  • [ ] 角色验证:管理员路由受角色检查保护吗?
  • [ ] 无客户端认证:授权在服务器端强制执行吗?

数据暴露

  • [ ] 最小化响应:API只返回必要字段吗?
  • [ ] URL中无敏感数据:令牌/ID不在查询字符串中吗?
  • [ ] 日志中无敏感数据:密码/令牌从日志中排除吗?

OWASP Top 10 快速检查

1. 注入(SQL、NoSQL、命令)

❌ db.query(`SELECT * FROM users WHERE id = ${userId}`);

✅ db.query('SELECT * FROM users WHERE id = ?', [userId]);

2. 破损认证

❌ if (req.headers.admin === 'true') { /* 允许管理员 */ }

✅ const user = await verifyToken(req.headers.authorization);
   if (user.role !== 'admin') throw new ForbiddenError();

3. 敏感数据暴露

❌ res.json({ user: { ...user, password, ssn } });

✅ res.json({ user: { id: user.id, name: user.name } });

4. 破损访问控制

❌ app.get('/users/:id', async (req, res) => {
     const user = await User.findById(req.params.id);
     res.json(user);
   });

✅ app.get('/users/:id', async (req, res) => {
     const user = await User.findById(req.params.id);
     if (user.id !== req.user.id && req.user.role !== 'admin') {
       throw new ForbiddenError();
     }
     res.json(user);
   });

5. 安全配置错误

❌ CORS: origin: '*'
❌ 生产环境中的详细错误消息
❌ 生产环境中启用调试模式

✅ CORS: origin: process.env.ALLOWED_ORIGINS
✅ 向客户端发送通用错误消息
✅ 生产环境中禁用调试模式

6. 跨站脚本(XSS)

❌ element.innerHTML = userInput;

✅ element.textContent = userInput;
✅ DOMPurify.sanitize(userInput);

苏格拉底式问题

向初级开发者提问而不是给出答案:

  1. 信任:“什么阻止恶意用户在这里发送任何他们想要的东西?”
  2. 所有权:“你怎么知道这个用户拥有这个资源?”
  3. 暴露:“如果这个端点暴露了,最坏的情况会发生什么?”
  4. 秘密:“如果我 git clone 这个仓库,我会看到什么秘密?”
  5. 注入:“如果有人发送 '; DROP TABLE users; -- 作为输入怎么办?”

需要指出的危险信号

标志 风险 问题
查询中的字符串拼接 SQL注入 “这个输入可以包含SQL吗?”
eval()new Function() 代码注入 “为什么需要动态代码执行?”
使用用户数据的 innerHTML XSS “如果用户包含 <script> 怎么办?”
日志中的密码 数据泄露 “谁能看到这些日志?”
认证上无限流 暴力破解 “什么阻止某人尝试每个密码?”
CORS: * 安全绕过 “任何网站都应该能够调用这个API吗?”
无过期的JWT 令牌盗窃 “如果这个令牌被盗会发生什么?”
URL中的ID IDOR “用户A可以通过更改ID访问用户B的数据吗?”

部署前安全清单

  1. [ ] 所有秘密在环境变量中
  2. [ ] 强制执行HTTPS
  3. [ ] 所有端点上的输入验证
  4. [ ] 防止SQL/NoSQL注入(参数化查询)
  5. [ ] 防止XSS(输出编码)
  6. [ ] 启用CSRF保护
  7. [ ] 认证端点上的速率限制
  8. [ ] 从响应中排除敏感数据
  9. [ ] 每个受保护路由上的授权检查
  10. [ ] 设置安全头部(helmet.js 或等效)

永远不要这样做

行动 原因
以明文存储密码 一次泄露暴露所有用户
将秘密放入代码 Git历史是永久的
仅信任客户端验证 任何人都可以绕过客户端
返回完整数据库对象 暴露内部字段
记录敏感数据 日志也会被泄露
使用 md5sha1 作为密码 密码学上已破损