名称: 安全模式
description: “安全模式和OWASP指南。触发条件:安全审查、OWASP、XSS、SQL注入、CSRF、身份验证、授权、密钥管理、输入验证、安全编码。”
兼容性: “语言无关模式,参考资料中包含框架特定示例。”
允许工具: “Read Write Bash Grep”
安全模式
Web应用程序的基本安全模式。
OWASP Top 10 快速参考
| 排名 |
漏洞类型 |
预防措施 |
| A01 |
失效的访问控制 |
服务器端检查权限,默认拒绝 |
| A02 |
加密机制失效 |
使用TLS,哈希密码,加密敏感数据 |
| A03 |
注入攻击 |
参数化查询,验证输入 |
| A04 |
不安全设计 |
威胁建模,安全默认设置 |
| A05 |
安全配置错误 |
强化配置,禁用未使用功能 |
| A06 |
易受攻击组件 |
更新依赖项,定期审计 |
| A07 |
身份验证失败 |
多因素认证,速率限制,安全会话管理 |
| A08 |
数据完整性失效 |
验证签名,使用可信来源 |
| A09 |
日志记录失败 |
记录安全事件,保护日志 |
| A10 |
服务器端请求伪造 |
验证URL,白名单目标地址 |
输入验证
# 错误 - 信任用户输入
def search(query):
return db.execute(f"SELECT * FROM users WHERE name = '{query}'")
# 正确 - 参数化查询
def search(query):
return db.execute("SELECT * FROM users WHERE name = ?", [query])
验证规则
始终验证:
- 类型(字符串、整数、邮箱格式)
- 长度(最小/最大边界)
- 范围(数值边界)
- 格式(正则表达式模式)
- 白名单(已知良好值)
切勿信任:
- URL参数
- 表单数据
- HTTP头部
- Cookies
- 文件上传
输出编码
// 错误 - 直接插入HTML
element.innerHTML = userInput;
// 正确 - 文本内容(自动转义)
element.textContent = userInput;
// 正确 - 带转义的模板
render(`<div>${escapeHtml(userInput)}</div>`);
按上下文编码
| 上下文 |
编码方式 |
| HTML正文 |
HTML实体编码 |
| HTML属性 |
属性编码 + 引号 |
| JavaScript |
JS编码 |
| URL参数 |
URL编码 |
| CSS |
CSS编码 |
身份验证
# 密码哈希(使用bcrypt、argon2或scrypt)
import bcrypt
def hash_password(password: str) -> bytes:
return bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
def verify_password(password: str, hashed: bytes) -> bool:
return bcrypt.checkpw(password.encode(), hashed)
身份验证检查清单
- [ ] 使用bcrypt/argon2哈希密码(成本因子12+)
- [ ] 在登录处实施速率限制
- [ ] 使用安全会话令牌(随机、长)
- [ ] 设置安全Cookie标志(HttpOnly、Secure、SameSite)
- [ ] 失败尝试后实施账户锁定
- [ ] 敏感操作支持多因素认证
授权
# 错误 - 仅检查身份验证
@login_required
def delete_post(post_id):
post = Post.get(post_id)
post.delete()
# 正确 - 检查授权
@login_required
def delete_post(post_id):
post = Post.get(post_id)
if post.author_id != current_user.id and not current_user.is_admin:
raise Forbidden("无权删除此帖子")
post.delete()
密钥管理
# 错误 - 硬编码密钥
API_KEY = "sk-1234567890abcdef"
# 正确 - 环境变量
API_KEY = os.environ["API_KEY"]
# 更好 - 密钥管理器
API_KEY = secrets_client.get_secret("api-key")
密钥处理规则
应该:
- 使用环境变量或密钥管理器
- 定期轮换密钥
- 不同环境使用不同密钥
- 审计密钥访问
不应该:
- 将密钥提交到git
- 记录密钥
- 在错误消息中包含密钥
- 明文共享密钥
安全头部
Content-Security-Policy: default-src 'self'; script-src 'self'
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Strict-Transport-Security: max-age=31536000; includeSubDomains
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=()
快速安全审计
# 查找硬编码密钥
rg -i "(password|secret|api_key|token)\s*=\s*['\"][^'\"]+['\"]" --type py
# 查找SQL注入风险
rg "execute\(f['\"]|format\(" --type py
# 查找eval/exec使用
rg "\b(eval|exec)\s*\(" --type py
# 检查TODO安全项
rg -i "TODO.*security|FIXME.*security"
附加资源
./references/owasp-detailed.md - 完整OWASP Top 10详情
./references/auth-patterns.md - JWT、OAuth、会话管理
./references/crypto-patterns.md - 加密、哈希、签名
./references/secure-headers.md - HTTP安全头部指南
脚本
./scripts/security-scan.sh - 快速安全grep模式
./scripts/dependency-audit.sh - 检查易受攻击依赖项