
关于
识别和处理代码中的尖锐边缘和潜在陷阱,防止常见的开发者错误。
name: sharp-edges description: "识别容易出错的 API、危险配置和导致安全错误的设计缺陷。在审查 API 设计、配置模式、加密库易用性或评估代码是否遵循安全设计原则时使用。" risk: unknown source: community
锋利边缘分析
评估 API、配置和接口是否能抵抗开发者误用。识别"简单路径"导致不安全的设计。
何时使用
- 审查 API 或库设计决策
- 审计配置模式中的危险选项
- 评估加密 API 的易用性
- 评估认证/授权接口
- 审查任何向开发者暴露安全相关选择的代码
何时不使用
- 实现缺陷(使用标准代码审查)
- 业务逻辑缺陷(使用领域特定分析)
- 性能优化(不同的关注点)
核心原则
成功之坑:安全使用应该是阻力最小的路径。如果开发者必须理解密码学、仔细阅读文档或记住特殊规则才能避免漏洞,那么 API 就失败了。
应拒绝的合理化借口
| 合理化借口 | 为什么是错的 | 必需的行动 | |------------|-------------|-----------| | "文档里写了" | 开发者在截止日期压力下不会阅读文档 | 让安全选择成为默认或唯一选项 | | "高级用户需要灵活性" | 灵活性制造陷阱;大多数"高级"用法是复制粘贴 | 提供安全的高级 API;隐藏原语 | | "这是开发者的责任" | 推卸责任;是你设计了这个陷阱 | 移除陷阱或使其不可能被误用 | | "没人会真的那样做" | 开发者在压力下会做出一切可以想象的事 | 假设开发者处于最大困惑状态 | | "这只是一个配置选项" | 配置就是代码;错误的配置会部署到生产环境 | 验证配置;拒绝危险组合 | | "我们需要向后兼容" | 不安全的默认值不能被豁免 | 大声弃用;强制迁移 |
锋利边缘类别
1. 算法/模式选择陷阱
让开发者选择算法的 API 会导致选择错误的算法。
JWT 模式(典型示例):
- 头部指定算法:攻击者可以设置
"alg": "none"来绕过签名 - 算法混淆:从 RS256 切换到 HS256 时,RSA 公钥被用作 HMAC 密钥
- 根本原因:让不受信任的输入控制安全关键决策
检测模式:
- 函数参数如
algorithm、mode、cipher、hash_type - 选择加密原语的枚举/字符串
- 安全机制的配置选项
示例 - PHP password_hash 允许弱算法:
// 危险:允许 crc32, md5, sha1
password_hash($password, PASSWORD_DEFAULT); // 好 - 无选择
hash($algorithm, $password); // 差:接受 "crc32"
2. 危险默认值
不安全的默认值,或禁用安全性的零/空值。
OTP 生命周期模式:
# lifetime=0 时会发生什么?
def verify_otp(code, lifetime=300): # 默认 300 秒
if lifetime == 0:
return True # 糟糕:0 意味着"接受所有"?
# 还是意味着"立即过期"?
检测模式:
- 接受 0 的超时/生命周期(无限?立即过期?)
- 绕过检查的空字符串
- 跳过验证的 null 值
- 禁用安全功能的布尔默认值
- 语义未定义的负值
要问的问题:
timeout=0会怎样?max_attempts=0?key=""?- 默认值是最安全的选项吗?
- 是否有任何默认值能完全禁用安全性?
3. 原语 vs. 语义 API
暴露原始字节而非有意义类型的 API 会导致类型混淆。
Libsodium vs. Halite 模式:
// Libsodium(原语):字节就是字节
sodium_crypto_box($message, $nonce, $keypair);
// 容易:交换 nonce/keypair,重用 nonce,使用错误的密钥类型
// Halite(语义):类型强制正确使用
Crypto::seal($message, new EncryptionPublicKey($key));
// 错误的密钥类型 = 类型错误,而非静默失败
检测模式:
- 对不同安全概念使用
bytes、string、[]byte的函数 - 可以在没有类型错误的情况下交换的参数
- 对密钥、nonce、密文、签名使用相同类型
比较陷阱:
// 时序安全比较看起来与不安全的相同
if hmac == expected { } // 差:时序攻击
if hmac.Equal(mac, expected) { } // 好:常量时间
// 相同类型,不同安全属性
4. 配置悬崖
一个错误的设置造成灾难性故障,且没有警告。
检测模式:
- 完全禁用安全性的布尔标志
- 未经验证的字符串配置
- 设置的组合
兼容工具
Claude CodeCursor
标签
前端开发