跳转到内容

威胁模型

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。应用提供的配置、证书、回调不视为攻击面。
  • 边界endpoint feed datagram 的入口(endpoint.zig / endpoint_lifecycle.zigprocessDatagram / receiveDatagramStep)。凡是跨过此边界的字节都必须先通过解析长度校验 + AEAD/密钥认证,才允许影响连接状态。
  • 3x anti-amplification budget:server 在 peer 地址验证前发送量 ≤ 收到的 3 倍。
    • 代码:src/quic/connection_rules.zigAntiAmplification)、src/quic/connection.zigantiAmplificationLimitRemaining / 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.zig retry 场景、tls13_server_endpoint_tests.zig
  • CID 路由 + TLS 1.3 AEAD 包保护:short-header 包用 server 发布的 CID 路由,payload 必须过 AEAD 认证才被接受;未认证包无法注入合法流。
    • 代码:src/quic/protection.zigunprotect*)、src/quic/connection.zigprocessProtectedShortDatagram)。
    • 测试:connection_tests.zig 注入/篡改/tamper 场景。
  • Initial 密钥派生绑定 Original DCID(RFC 9001 §5.2):client Initial 的密钥由 client 选择的 DCID 派生,攻击者无法预知/复用,防止伪造 Initial 前缀。
    • 代码:src/quic/protection.zigderiveInitialSecrets)、src/quic/tls13_server_transport.zigsetOriginalDestinationConnectionId)。
    • 测试:connection_tests.zig Initial 密钥派生测试。
  • 16 字节 stateless reset token(2^128 暴力不可行),经 NEW_CONNECTION_ID transport parameter 协商。
    • 代码:src/quic/packet.zigmatchesStatelessReset)、src/quic/connection.zig(token 匹配状态)、src/quic/connection_config.zig
    • 测试:connection_tests.zig stateless reset token 匹配/拒绝;examples/stateless_reset.zigexamples/tls13_stateless_reset_loopback.zig
  • version_information 校验 chosen/available/reserved,拒绝降级攻击(RFC 9369 §3)。
    • 代码:src/quic/connection_version.zigsrc/quic/connection.zig
    • 测试:quic_v2_test.zigconnection_tests.zig version negotiation / v2 场景。
  • 范围校验(max_udp_payload / ack_delay / streams)、duplicate 检测、CID len ≤ 20。
    • 代码:src/quic/connection_config.zigsrc/quic/connection_rules.zig
    • 测试:connection_tests.zig transport 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.zig hostile max_idle_timeout 溢出防护。
  • Retry token 用 AEAD 认证(绑定 kind/lifetime/address),无法伪造。
    • 代码:src/quic/endpoint.zig / endpoint_lifecycle.zig(token 签发与校验)、src/quic/protection.zig
    • 测试:connection_tests.zig retry 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 在声明长度上 enforce max_frame_payload_size(16 MiB),超长帧先于任何下游分配被拒(validateFrameSize)。
    • 代码:src/h3/frame.zigdecodeFrame)、src/h3/limits.zigvalidateFrameSize)。
    • 测试:frame.zig “HTTP/3 oversized frame payload is rejected”。
  • header 字段数上限:QPACK 解码写固定 out_fields 数组,超限 error.TooManyFields(调用方 request 用 [32] 数组)。
    • 代码:src/h3/qpack.zigdecodeHeaderBlock)、src/h3/request.zig
  • header 名/值长度 + 大小写:request/response 解码循环对每个字段 enforce validateHeaderField(name≤256、value≤8192、无大写)。
    • 代码:src/h3/request.zigsrc/h3/limits.zigvalidateHeaderField)。
    • 测试:request.zig “HTTP/3 request rejects uppercase header name”。
  • SETTINGS 参数数上限decodePayload 计数并 enforce max_settings_params(32),防无限 SETTINGS 参数 DoS。
    • 代码:src/h3/connection.zigdecodePayload)、src/h3/limits.zigvalidateSettingsCount)。
    • 测试:connection.zig “Settings decode rejects oversized parameter count”。
  • QPACK 静态表索引越界 / 字符串越界:QPACK 解码校验静态表索引与字符串长度,越界返回错误而非溢出。
    • 代码:src/h3/qpack.zigdecodeHeaderBlock / decodeString)。

以下不在 quicz 库内,由嵌入方(runtime / 应用)负责:

  • socket bind / 超时 / 并发上限;
  • TLS 证书验证策略(ca_bundleserver_nameinsecure_skip_verify 的选用);
  • idle timeout、连接数、流数上限配置;
  • 部署级防护(防火墙、DDoS、NAT 处理)。
  1. fuzz 交互面已上、OSS-Fuzz 未接入fuzzDriveConnectionStateMachine(1-RTT 连接状态机交互)+ C ABI quicz_fuzz_drive + .oss-fuzz/ 脚手架已落地(见 src/quic/fuzz_c_abi.zig),但实际接入 OSS-Fuzz 需向 oss-fuzz 项目提交(外部队列,非仓库内可完成)。
  2. QPACK 动态表DynamicTable 有容量上限 + eviction,但动态表增删改的端到端解码路径未纳入交互 fuzz。
  3. 证书策略默认值insecure_skip_verify 或空 ca_bundle 会跳过证书验证,属 integrator 责任,但库默认应偏保守。
攻击 防御层 状态
放大攻击 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 上限 已实现 + 测试