惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
云风的 BLOG
云风的 BLOG
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Palo Alto Networks Blog
D
Docker
H
Hackread – Cybersecurity News, Data Breaches, AI and More
S
Schneier on Security
Engineering at Meta
Engineering at Meta
I
InfoQ
L
LangChain Blog
Cyberwarzone
Cyberwarzone
T
Tenable Blog
WordPress大学
WordPress大学
P
Privacy & Cybersecurity Law Blog
罗磊的独立博客
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Jina AI
Jina AI
C
CERT Recently Published Vulnerability Notes
Scott Helme
Scott Helme
博客园 - 三生石上(FineUI控件)
酷 壳 – CoolShell
酷 壳 – CoolShell
Know Your Adversary
Know Your Adversary
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Last Watchdog
The Last Watchdog
Last Week in AI
Last Week in AI
Cloudbric
Cloudbric
S
SegmentFault 最新的问题
爱范儿
爱范儿
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 叶小钗
AI
AI
T
Tor Project blog
I
Intezer
T
Threatpost
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V
Visual Studio Blog
N
News and Events Feed by Topic
Latest news
Latest news
S
Security Affairs
博客园 - Franky
Microsoft Security Blog
Microsoft Security Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
B
Blog RSS Feed
C
Cybersecurity and Infrastructure Security Agency CISA
Hugging Face - Blog
Hugging Face - Blog
小众软件
小众软件
S
Securelist

博客园 - toong

P2P与FRP与websocket python运行虚拟化环境 大模型从0到1 绑定网卡中断后是否需要设置RFS linux socket reuse port 小测试 现代C++ envoy timeout 说明 观察中断的脚本 /proc/interrupts openssl查看编译时选项设置的方法 内核ipsec转发优化方法 提高ipsec多核并行能力的优化方法之一 tc qdisc 的burst如何设置 bash模拟netstat取值的脚本 linux内核对MSI网卡队列的smp_affinity亲和CPU选择 bash多并发--进程池数量控制 bash单例模式 linux 分析中断 linux 查看 ipsec 丢包 linux内核rps与rfs机制分析 linux获取CPU利用率的快捷命令 开启openssl legacy的方法
envoy DDOS HTTP/2 Bomb CVE-2026-47774 安全漏洞分析
toong · 2026-06-18 · via 博客园 - toong

漏洞介绍

https://access.redhat.com/zh_CN/security/vulnerabilities/RHSB-2026-007

https://blog.calif.io/p/codex-discovered-a-hidden-http2-bomb

https://github.com/envoyproxy/envoy/security/advisories/GHSA-22m2-hvr2-xqc8

https://github.com/envoyproxy/envoy/security/advisories/GHSA-22m2-hvr2-xqc8

攻击原理

攻击者先往 HPACK 动态表植入一个大头部(如 4KB 的 Cookie)
↓
然后在单个请求里塞几千个"单字节索引引用"(Index 62, Index 62, Index 62...)
↓
服务器为每个引用重建/追加完整头部副本 → 内存 × 数千倍放大
↓
同时宣告 INITIAL_WINDOW_SIZE = 0(零窗口)→ 响应发不出去,流永远卡着
↓
已分配的内存放在那里不释放 → 10~20 秒内吃光 32GB RAM → OOM Kill / 拒绝服务

漏洞修复

1.38 的官方修复

https://github.com/envoyproxy/envoy/pull/45518/changes

openssl 1.23的修复

https://github.com/envoyproxy/envoy-openssl/pull/553

https://github.com/envoyproxy/envoy-openssl/pull/562

image

有效的关键修复

  • 3de6178c43 — CVE-2026-47774 基础修复
  • 28e883a749 — 补充 cookie 大小限制

https://github.com/envoyproxy/envoy-openssl/commit/3de6178c4353078e564d327061fe36c93dbd58c9

https://github.com/envoyproxy/envoy-openssl/commit/28e883a7490f856efab9645f39da9c58266aad7c

修复总结

核心改动

把解压的cookie分别计入 header 大小与header长度。

加了一个feature,默认开启

envoy.reloadable_features.http2_include_cookies_in_limits

在runtime_features.cc中设置,默认值为true。

加了两个监控统计

header_list_size_too_large

cookies_total_bytes_too_large

加了一个配置

envoy.reloadable_features.http2_max_cookies_size_in_kb  默认值为0.

使用了一个原有配置

max header byte

max header count

是HCM的两个配置项:

maxRequestHeadersKb   默认值 60KB

https://www.envoyproxy.io/docs/envoy/v1.32.13/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#extensions-filters-network-http-connection-manager-v3-httpconnectionmanager

maxReqestHeadersCount  默认值 100

https://www.envoyproxy.io/docs/envoy/v1.32.13/api-v3/config/core/v3/protocol.proto#envoy-v3-api-msg-config-core-v3-httpprotocoloptions

image

image

代码分析

后续部分为AI生成,后进行的二次整理。

source/common/http/http2/codec_impl.h

Stream 新增 cookie_count_ 字段,记录拆分出的 cookie header 条数:

HeaderString cookies_;        // 解压后拼接的 cookie 字符串(已有)
uint32_t cookie_count_;       // cookie header 条数(新增)

source/common/http/http2/codec_impl.ccsaveHeader()

HPACK 解压出的每个 header 进入 saveHeader()。如果是 cookie(被 reconstituteCrumbledCookies 识别并拼接到 cookies_),计数加一:

if (Utility::reconstituteCrumbledCookies(name, value, cookies_)) {
    cookie_count_++;   // cookie 条数 +1
} else {
    headers().addViaMove(std::move(name), std::move(value));
}

source/common/http/http2/codec_impl.ccsaveHeader() 限制检查

原来的合并检查被拆分为三部分,每部分有独立的 error detail 和 counter:

检查项

触发条件

Error Detail

header 总大小超限

(headers + cookies).byteSize > max_headers_kb * 1024

http2.header_list_size_too_large

header 总数超限

(headers + cookies).count > max_headers_count

http2.too_many_headers

uint64_t headers_size = stream->headers().byteSize();
uint64_t headers_count = stream->headers().size();

// runtime guard 控制是否将 cookie 纳入计算(默认开启)
if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.http2_include_cookies_in_limits")) {
    headers_size += stream->cookies_.size();      // cookie 字节数计入
    headers_count += stream->cookie_count_;        // cookie 条数计入
}

if (headers_size > max_headers_kb_ * 1024) {
    stream->setDetails(Http2ResponseCodeDetails::get().header_list_size_too_large);
    stats_.header_list_size_too_large_.inc();
    return ERR_TEMPORAL_CALLBACK_FAILURE;  // → RST_STREAM
}
if (headers_count > max_headers_count_) {
    stream->setDetails(Http2ResponseCodeDetails::get().too_many_headers);
    stats_.header_overflow_.inc();
    return ERR_TEMPORAL_CALLBACK_FAILURE;
}
return 0;

source/common/http/http2/codec_stats.h — 新 counter:

COUNTER(header_list_size_too_large)   // 总 header 大小超限(区别于 header_overflow)
COUNTER(cookies_total_bytes_too_large) // cookie 重组大小超限

source/common/runtime/runtime_features.cc — Runtime guard:

RUNTIME_GUARD(envoy_reloadable_features_http2_include_cookies_in_limits);

新增独立的 http2_max_cookies_size_in_kb runtime guard,直接限制重组后 cookies 的总字节数,不依赖其他 header 累积的影响。

source/common/http/http2/codec_impl.h

ConnectionImpl 构造函数新增 runtime 参数和 max_cookie_size_bytes_ 成员:

ConnectionImpl(...
    const uint32_t max_headers_kb, const uint32_t max_headers_count,
    OptRef<Runtime::Loader> runtime = absl::nullopt);  // 默认值保证向后兼容

const uint64_t max_cookie_size_bytes_{0};  // 0 = 不限制

ServerConnectionImpl 同样新增 runtime 参数并传递给父类:

ServerConnectionImpl(...,
    Server::OverloadManager& overload_manager,
    OptRef<Runtime::Loader> runtime = absl::nullopt);

source/common/http/http2/codec_impl.cc — 构造函数

从 runtime snapshot 读取配置值(KB → 字节):

max_cookie_size_bytes_(
    runtime.has_value()
        ? runtime->snapshot().getInteger(
              "envoy.reloadable_features.http2_max_cookies_size_in_kb", 0) * 1024
        : 0)

source/common/http/http2/codec_impl.ccsaveHeader() 新增检查

在三层检查的最前面,独立判断 cookie 重组大小:

const uint64_t total_cookie_size = stream->cookies_.size();
if (max_cookie_size_bytes_ > 0 && total_cookie_size > max_cookie_size_bytes_) {
    stream->setDetails(Http2ResponseCodeDetails::get().cookies_total_bytes_too_large);
    stats_.cookies_total_bytes_too_large_.inc();
    return ERR_TEMPORAL_CALLBACK_FAILURE;
}

调用链传递 runtime 参数:

conn_manager_utility.ccautoCreateCodec() 新增 Runtime::Loader& 参数:

ServerConnectionPtr autoCreateCodec(..., Server::OverloadManager& overload_manager,
                                    Runtime::Loader& runtime);

在创建 Http2::ServerConnectionImpl 时传入 runtime。

config.cc — HCM 创建 codec 时传递 runtime:

context_.serverFactoryContext().runtime()

admin.cc — Admin 接口创建 codec 时传递 runtime:

server_.runtime()
                    ┌─────────────────────────────────────┐
                    │     HPACK 解压 header                │
                    │           ↓                          │
                    │  saveHeader()                        │
                    │           ↓                          │
                    │  cookie? → cookies_ += value         │
                    │           → cookie_count_++          │
                    │  other?  → headers().add()           │
                    │           ↓                          │
                    │  ┌──── 三层检查 ────┐               │
                    │  │                                       │
                    │  │ 1. cookies_.size()                    │
                    │  │    > max_cookie_size_bytes_?          │
                    │  │    → cookies_total_bytes_too_large    │
                    │  │                                       │
                    │  │ 2. (headers + cookies).byteSize       │
                    │  │    > max_headers_kb * 1024?           │
                    │  │    → header_list_size_too_large       │
                    │  │                                       │
                    │  │ 3. (headers + cookies).count          │
                    │  │    > max_headers_count?               │
                    │  │    → too_many_headers                 │
                    │  │                                       │
                    │  └───────────────────────────────────────┘
                    │           ↓
                    │  ERR_TEMPORAL_CALLBACK_FAILURE
                    │           ↓
                    │       RST_STREAM
                    └─────────────────────────────────────┘

防御层

来源

Runtime Guard

Cookie 独立大小限制

28e883a749

http2_max_cookies_size_in_kb

Cookie 参与 header 总大小限制

3de6178c43

http2_include_cookies_in_limits

Cookie 参与 header 总数量限制

3de6178c43

http2_include_cookies_in_limits

默认值安全:两个 guard 默认均启用保护,http2_max_cookies_size_in_kb 默认 0(无单独限制,依赖总大小限制生效)