威胁模型
quicz 的威胁模型:明确 trust boundary、每种在本库范围内可防御的攻击类型、对应的代码+测试引用, 以及 integrator(嵌入式使用者)必须自行承担的安全职责。文档目标是让安全审计者能按图索骥核对 每一层防御。镜像自仓库 THREAT_MODEL.md。
- In scope:QUIC v1/v2 传输(RFC 9000 / RFC 9369)、TLS 1.3 握手与包保护(RFC 8446 / RFC 9001)、丢包恢复与拥塞控制(RFC 9002)、HTTP/3 应用层(RFC 9114)。
- Out of scope:socket 生命周期(由 runtime/调用方负责)、TLS 证书策略(由调用方配置)、应用业务逻辑、部署防火墙/网络拓扑。
- 入站 UDP datagram = hostile。攻击者完全控制 wire 输入:可构造畸形包、分片、重放、伪造源地址、任意注入。所有入站路径都按不可信数据严格解析 + 认证。
- 调用方(嵌入 quicz 的应用)= trusted。应用提供的配置、证书、回调不视为攻击面。
- 边界:
endpointfeed datagram 的入口(endpoint.zig/endpoint_lifecycle.zig的processDatagram/receiveDatagramStep)。凡是跨过此边界的字节都必须先通过解析长度校验 + AEAD/密钥认证,才允许影响连接状态。
放大攻击(RFC 9000 §8.1)
Section titled “放大攻击(RFC 9000 §8.1)”- 3x anti-amplification budget:server 在 peer 地址验证前发送量 ≤ 收到的 3 倍。
- 代码:
src/quic/connection_rules.zig(AntiAmplification)、src/quic/connection.zig(antiAmplificationLimitRemaining/recordPeerAddressBytesReceived)。 - 测试:
connection_tests.zig“server anti-amplification limit disarms PTO until more peer bytes arrive” 等。
- 代码:
- Retry 地址验证:server 用 Retry 包 + AEAD 认证 token 验证 source address,未验证前不放大。
- 代码:
src/quic/endpoint.zig/src/quic/endpoint_lifecycle.zig(Retry 构造与 token 校验)、src/quic/protection.zig(Retry Integrity Tag)。 - 测试:
connection_tests.zigretry 场景、tls13_server_endpoint_tests.zig。
- 代码:
包注入 / 伪造
Section titled “包注入 / 伪造”- CID 路由 + TLS 1.3 AEAD 包保护:short-header 包用 server 发布的 CID 路由,payload 必须过 AEAD 认证才被接受;未认证包无法注入合法流。
- 代码:
src/quic/protection.zig(unprotect*)、src/quic/connection.zig(processProtectedShortDatagram)。 - 测试:
connection_tests.zig注入/篡改/tamper 场景。
- 代码:
- Initial 密钥派生绑定 Original DCID(RFC 9001 §5.2):client Initial 的密钥由 client 选择的 DCID 派生,攻击者无法预知/复用,防止伪造 Initial 前缀。
- 代码:
src/quic/protection.zig(deriveInitialSecrets)、src/quic/tls13_server_transport.zig(setOriginalDestinationConnectionId)。 - 测试:
connection_tests.zigInitial 密钥派生测试。
- 代码:
Stateless reset token 猜测
Section titled “Stateless reset token 猜测”- 16 字节 stateless reset token(2^128 暴力不可行),经 NEW_CONNECTION_ID transport parameter 协商。
- 代码:
src/quic/packet.zig(matchesStatelessReset)、src/quic/connection.zig(token 匹配状态)、src/quic/connection_config.zig。 - 测试:
connection_tests.zigstateless reset token 匹配/拒绝;examples/stateless_reset.zig、examples/tls13_stateless_reset_loopback.zig。
- 代码:
版本协商降级
Section titled “版本协商降级”version_information校验 chosen/available/reserved,拒绝降级攻击(RFC 9369 §3)。- 代码:
src/quic/connection_version.zig、src/quic/connection.zig。 - 测试:
quic_v2_test.zig、connection_tests.zigversion negotiation / v2 场景。
- 代码:
Transport parameter 恶意值
Section titled “Transport parameter 恶意值”- 范围校验(max_udp_payload / ack_delay / streams)、duplicate 检测、CID len ≤ 20。
- 代码:
src/quic/connection_config.zig、src/quic/connection_rules.zig。 - 测试:
connection_tests.zigtransport parameter 校验。
- 代码:
- max_idle_timeout cap(已修复,commit f7c89b4):hostile peer 可传极大 max_idle_timeout,若不做 cap 会 ms→ns 乘法溢出导致无意义/异常 deadline。已 cap 到安全上限。
- 代码:
src/quic/connection_config.zig(idle timeout 归一/封顶)。 - 测试:
connection_tests.zighostile max_idle_timeout 溢出防护。
- 代码:
Retry token 伪造
Section titled “Retry token 伪造”- Retry token 用 AEAD 认证(绑定 kind/lifetime/address),无法伪造。
- 代码:
src/quic/endpoint.zig/endpoint_lifecycle.zig(token 签发与校验)、src/quic/protection.zig。 - 测试:
connection_tests.zigretry token 伪造拒绝。
- 代码:
H3/QPACK 应用层资源耗尽(RFC 9114 §4.6 / RFC 9204 §3.2)
Section titled “H3/QPACK 应用层资源耗尽(RFC 9114 §4.6 / RFC 9204 §3.2)”HTTP/3 在 QUIC 之上,入站 HEADERS/SETTINGS/DATA 帧与 QPACK header block 同样 hostile。已接线资源上限,防 header 字段数、frame 载荷、header 名/值长度、SETTINGS 参数数导致的分配放大:
- frame 载荷大小上限:
decodeFrame在声明长度上 enforcemax_frame_payload_size(16 MiB),超长帧先于任何下游分配被拒(validateFrameSize)。- 代码:
src/h3/frame.zig(decodeFrame)、src/h3/limits.zig(validateFrameSize)。 - 测试:
frame.zig“HTTP/3 oversized frame payload is rejected”。
- 代码:
- header 字段数上限:QPACK 解码写固定
out_fields数组,超限error.TooManyFields(调用方 request 用[32]数组)。- 代码:
src/h3/qpack.zig(decodeHeaderBlock)、src/h3/request.zig。
- 代码:
- header 名/值长度 + 大小写:request/response 解码循环对每个字段 enforce
validateHeaderField(name≤256、value≤8192、无大写)。- 代码:
src/h3/request.zig、src/h3/limits.zig(validateHeaderField)。 - 测试:
request.zig“HTTP/3 request rejects uppercase header name”。
- 代码:
- SETTINGS 参数数上限:
decodePayload计数并 enforcemax_settings_params(32),防无限 SETTINGS 参数 DoS。- 代码:
src/h3/connection.zig(decodePayload)、src/h3/limits.zig(validateSettingsCount)。 - 测试:
connection.zig“Settings decode rejects oversized parameter count”。
- 代码:
- QPACK 静态表索引越界 / 字符串越界:QPACK 解码校验静态表索引与字符串长度,越界返回错误而非溢出。
- 代码:
src/h3/qpack.zig(decodeHeaderBlock/decodeString)。
- 代码:
Integrator 职责
Section titled “Integrator 职责”以下不在 quicz 库内,由嵌入方(runtime / 应用)负责:
- socket bind / 超时 / 并发上限;
- TLS 证书验证策略(
ca_bundle、server_name、insecure_skip_verify的选用); - idle timeout、连接数、流数上限配置;
- 部署级防护(防火墙、DDoS、NAT 处理)。
- fuzz 交互面已上、OSS-Fuzz 未接入:
fuzzDriveConnectionStateMachine(1-RTT 连接状态机交互)+ C ABIquicz_fuzz_drive+.oss-fuzz/脚手架已落地(见src/quic/fuzz_c_abi.zig),但实际接入 OSS-Fuzz 需向 oss-fuzz 项目提交(外部队列,非仓库内可完成)。 - QPACK 动态表:
DynamicTable有容量上限 + eviction,但动态表增删改的端到端解码路径未纳入交互 fuzz。 - 证书策略默认值:
insecure_skip_verify或空ca_bundle会跳过证书验证,属 integrator 责任,但库默认应偏保守。
攻防对照小结
Section titled “攻防对照小结”| 攻击 | 防御层 | 状态 |
|---|---|---|
| 放大攻击 | anti-amplification 3x + Retry 地址验证 | 已实现 + 测试 |
| 包注入/伪造 | CID 路由 + AEAD + Initial 密钥绑定 DCID | 已实现 + 测试 |
| stateless reset token 猜测 | 16 字节 token | 已实现 + 测试 |
| 版本降级 | version_information 校验 | 已实现 + 测试 |
| transport parameter 恶意值 | 范围校验 + max_idle_timeout cap | 已实现 + 测试 |
| Retry token 伪造 | AEAD 认证 | 已实现 + 测试 |
| H3/QPACK 资源耗尽 | frame/header/settings 上限 | 已实现 + 测试 |