Istio HTTP/2 HPACK 放大攻击:Cookie 头绕过限流致 OOM,速查升级路径

2026-06-04 20 预计阅读时间:1 分钟
来源:istio.io AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:7 分钟

Istio 近期披露了安全公告 ISTIO-SECURITY-2026-004,对应 CVE-2026-47774,CVSS 评分 7.5(High)。漏洞根因落在 Envoy 的 HTTP/2 头部处理逻辑上——HPACK 编码的压缩率让攻击者用极小的请求体撑爆 Sidecar 内存。任何对外暴露 HTTP/2 或 gRPC 的 Istio 集群都在攻击面内,无需认证即可触发。

漏洞机制:编码字节 ≠ 解码字节

HTTP/2 使用 HPACK 算法压缩头部。HPACK 维护一张动态表,重复出现的头部字段(如 cookie)只需引用表中的索引,编码体积可以非常小。

问题出在两处校验的脱节:

  1. Cookie 头字节未纳入请求头大小校验——Envoy 在验证请求头总大小时,没有完整统计 cookie 头占用的字节数。Cookie 本身就是 HTTP 中最容易膨胀的字段(多值、长 token),绕过了这一关就已经放大了攻击空间。

  2. HPACK 块限制只看编码字节,不看解码字节——Envoy 对 HPACK header block 设了上限,但这个上限作用于 编码后 的字节数。HPACK 的压缩特性意味着:一个索引引用可能只占 1–2 字节编码,解码后还原出几百甚至上千字节的原始头部。攻击者反复发送大量引用同一 cookie 的请求,编码侧始终"合规",解码侧内存持续膨胀。

最终结果:Envoy 进程内存耗尽,被 OOM Killer 终止,所在 Pod 重启——服务拒绝。

影响范围:比你想象的更广

受影响版本:

Istio 版本 受影响范围 修复版本
1.30.x 1.30.0 ≥ 1.30.1
1.29.x 1.29.0 – 1.29.3 ≥ 1.29.4
1.28.x 1.28.0 – 1.28.7 ≥ 1.28.8

触发条件只有一个:接受下游 HTTP/2 流量。以下场景均命中:

  • Gateway 暴露 HTTPS 端口(TLS 解密后内部走 HTTP/2)
  • Sidecar 接收来自集群内 gRPC 客户端的请求
  • 任何对不可信工作负载开放 HTTP/2 的 Service

注意:即便攻击者走 HTTPS 入站,TLS 终止后 Envoy 仍然以 HTTP/2 处理请求,漏洞照样触发。

紧急排查与升级

先确认集群 Istio 版本和流量暴露面,再执行升级。

1. 查当前 Istio 版本

# 查看控制面版本
istioctl version

# 或直接看 Pilot Pod 的镜像 tag
kubectl get deploy -n istio-system istiod -o jsonpath='{.spec.template.spec.containers[0].image}'

输出类似 gcr.io/istio-release/pilot:1.29.3——落在受影响区间就需要升级。

2. 查哪些 Gateway/Sidecar 接收 HTTP/2

# 查 Ingress Gateway 配置中 HTTP/2 相关端口
kubectl get svc -n istio-system istio-ingressgateway -o yaml | \
  grep -A2 -E 'name:.*https|name:.*http2|name:.*grpc'

# 查集群内 gRPC 服务(Service name 含 grpc 或 port name 含 grpc)
kubectl get svc --all-namespaces -o json | \
  jq -r '.items[] | select(.spec.ports[]?.name | test("grpc|h2")) | "\(.metadata.namespace)/\(.metadata.name)"'

任何匹配结果都意味着该路径可被利用。

3. 升级 Istio

以 1.29.3 升级到 1.29.4 为例:

# 下载目标版本 istioctl
curl -L https://istio.io/downloadIstio?ISTIO_VERSION=1.29.4 | sh -
cd istio-1.29.4

# 执行升级(先控制面,再数据面)
./bin/istioctl upgrade

# 等待 istiod 就绪后,滚动重启 Sidecar 注入的工作负载
kubectl rollout restart deployment --all-namespaces

# 确认新版本生效
istioctl version

升级前在非生产环境验证兼容性。Istio 小版本升级(1.29.3 → 1.29.4)通常只含 bugfix 和安全补丁,API 无变化,但仍建议走标准变更流程。

临时缓解:升级前的止损手段

如果无法立即升级,可以通过 EnvoyFilter 限制 HTTP/2 解码后的头部总大小,缩小攻击窗口:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: h2-header-size-guard
  namespace: istio-system
spec:
  configPatches:
    - applyTo: NETWORK_FILTER
      match:
        context: ANY
      patch:
        operation: MERGE
        value:
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
            max_request_headers_kb: 32
            http2_protocol_options:
              max_concurrent_streams: 100
              initial_stream_window_size: 65536

关键参数说明:

  • max_request_headers_kb: 32——将请求头总大小上限压到 32 KB(默认 96 KB),限制单次请求的头部膨胀空间。
  • initial_stream_window_size: 65536——缩小 HTTP/2 流级窗口,减缓大头部请求的传输速率。

这不能根治漏洞(编码侧校验仍然缺失),但能显著降低单次攻击的内存消耗量,争取升级时间。

修复后的验证清单

升级完成后,做以下确认:

检查项 命令/方法
Istiod 版本 ≥ 修复版本 istioctl version
Sidecar 镜像版本同步更新 kubectl get po -n app -c istio-proxy -o jsonpath='{.spec.containers[0].image}'
EnvoyFilter 缓解规则可移除 确认升级后删除临时 EnvoyFilter,避免限流参数影响正常大头部业务
Gateway 正常转发 HTTP/2 curl --http2 或 grpcurl 对外部服务发请求,确认无异常
OOM 事件消失 kubectl events --all-namespaces --field-selector reason=OOMKilling 近期无新记录

留一个意识:HPACK 是 HTTP/2 的通用风险

这次漏洞的本质是"压缩侧限流、解压侧不限流"——这类问题不只出现在 Envoy。任何实现 HTTP/2 HPACK 的代理(Nginx、HAProxy、Go net/http2)都可能存在类似设计盲区。排查时不妨一并检查集群中非 Istio 的 HTTP/2 代理配置,确认它们对 解码后 头部大小有独立上限。

升级是必须的,但理解机制才能在下一次同类漏洞出现时更快反应。


相关推荐