6. Security Considerations (安全考虑)
大小限制问题
结构化字段定义的大多数类型的大小没有限制;因此,极大的字段可能成为攻击向量(例如,用于资源消耗攻击)。
缓解措施
大多数HTTP实现限制以下内容的大小以缓解此类攻击:
- 单个字段的大小
- 整个头部区段的大小
- 整个尾部区段的大小
推荐做法
实现应该:
- 设置合理的字段大小限制
- 监控总头部大小
- 对异常大的字段值记录警报
- 考虑拒绝过大的请求/响应
字段注入攻击
具有注入新HTTP字段能力的方可以改变结构化字段的含义。
问题场景
# 原始请求
Example-Dict: key1=value1
# 攻击者注入额外的字段行
Example-Dict: key1=value1
Example-Dict: key2=malicious ← 注入
# 根据HTTP规则,这些会被合并
# 结果: key1=value1, key2=malicious
风险
在某些情况下,这会导致解析失败,但无法在所有情况下可靠地失败。
防御策略
-
严格的访问控制
- 限制谁可以设置HTTP字段
- 验证中间代理的行为
-
字段完整性验证
- 使用签名或HMAC保护关键字段
- 检测意外的字段修改
-
最小权限原则
- 限制字段的语义影响范围
- 不要让单个字段承载过多安全决策
解析严格性的安全意义
为什么严格解析是安全特性
场景: 恶意构造的字段值
宽容解析器:
Input: key="value\x00hidden"
可能解析为: key="value" (忽略空字节后的内容)
→ 隐藏的数据可能绕过安全检查
严格解析器:
Input: key="value\x00hidden"
结果: 解析失败,忽略整个字段
→ 没有歧义,安全边界清晰
安全优势
- 防止注入: 严格验证防止注入攻击
- 消除歧义: 所有实现行为一致
- 尽早失败: 在边界检查点发现问题
- 可预测性: 攻击者无法利用解析差异
类型混淆攻击
问题
// 字段定义: Example-Field必须是Integer
Example-Field: "123" // String类型
// 错误的实现可能:
value = parseInt(fieldValue); // 转换成功
// 但这违反了规范!
正确做法
// 严格类型检查
const field = parseItem(fieldValue);
if (field.type !== 'integer') {
// 忽略整个字段
return null;
}
资源消耗攻击示例
攻击1: 极长的List
# 包含100,000个成员的List
Example-List: 1, 2, 3, ..., 100000
影响: 内存耗尽、CPU过载
防御:
const MAX_LIST_SIZE = 1024; // RFC最小要求
if (list.length > MAX_LIST_SIZE) {
throw new Error('List too large');
}
攻击2: 深度嵌套
# 虽然RFC 8941限制了嵌套深度
# 但实现仍需小心
Example-List: ((((((((value))))))))
防御: RFC 8941的设计已经限制了嵌套(最多2层)
攻击3: 极长的字符串
Example-String: "AAAA...AAAA" (100MB)
防御:
const MAX_STRING_LENGTH = 8192; // 示例限制
if (string.length > MAX_STRING_LENGTH) {
throw new Error('String too long');
}
参数污染
问题
Example-Item: value; key=1; key=2; key=3
# 同一个键出现多次
RFC 8941的处理
参数键在其范围内必须是唯一的。重复的键会导致解析失败。
实现建议
const params = new Map();
for (const [key, value] of parsedParams) {
if (params.has(key)) {
throw new Error('Duplicate parameter key');
}
params.set(key, value);
}
与其他安全机制的交互
1. Content Security Policy (CSP)
结构化字段可用于CSP相关的头部:
# 假设的结构化CSP指令
Content-Security-Policy-Structured:
script-src=(self "nonce-abc123"),
style-src=(self)
2. CORS
# 现有的CORS头部
Access-Control-Allow-Origin: https://example.com
# 未来可能的结构化版本
Access-Control-Allow-Origins: "https://example.com",
"https://trusted.com"
3. Cookie安全
虽然Cookie不使用结构化字段(历史原因),但新的类似机制可以受益于结构化字段的严格性。
安全清单
实现结构化字段时,确保:
- 限制字段大小
- 限制List/Dictionary成员数量
- 限制字符串/Token长度
- 限制Byte Sequence大小
- 严格验证所有类型
- 拒绝重复的键
- 记录异常输入
- 测试边界情况
- 不尝试"修复"错误输入
- 在失败时忽略整个字段
关键要点
- 大小限制: 实现必须限制字段大小以防止资源耗尽
- 注入风险: 字段注入可能改变语义,但无法完全防止
- 严格解析: 严格性是安全特性,不是缺陷
- 类型安全: 严格的类型检查防止混淆攻击
- 实现责任: 实现者需要添加合理的安全限制
- 防御深度: 结合多种安全机制,不要仅依赖字段验证