CVE-2026-9848 是一个未认证的 SQL 注入(SQLi)漏洞,影响 WordPress 的 WP Ticket (Customer Support Ticket System & Helpdesk) 插件,版本 6.0.4 及更早版本。该漏洞的产生是因为插件获取 WordPress 搜索参数 s,并将其直接拼接到 UNION 子查询中的 SQL LIKE 子句内,而没有使用 $wpdb->prepare() 或进行适当的转义。因此,远程攻击者可以在未认证的情况下操纵数据库查询并提取敏感信息。
| 属性 | 值 |
|---|---|
| 产品 | WP Ticket (Customer Support Ticket System & Helpdesk) |
| 受影响版本 | ≤ 6.0.4 |
| 修复版本 | 6.0.5 |
| 受影响组件 | 前端搜索(s 参数) |
该插件通过 wp_ticket_com_posts_request() 挂接 WordPress 的 posts_request 过滤器。在未认证的前端搜索过程中,它最终会调用 emd_author_search_results(),后者会读取搜索参数:
$query->query_vars['s']
此时,WordPress 已使用 wp_unslash() 移除了魔术引号。该插件没有安全地对 SQL 语句进行参数化,而是将原始用户输入直接拼接到 UNION 子查询中的 SQL LIKE 子句内。
概念上:
User searches website
│
▼
Search parameter "s" received
│
▼
Plugin concatenates value into SQL query
│
▼
No $wpdb->prepare()
│
▼
Database executes modified query
该漏洞的存在是因为不受信任的输入通过字符串拼接被并入 SQL,而非使用参数化查询。
漏洞的核心在于插件如何构建其主 SQL 查询:
sql
SELECT * FROM wp_posts
WHERE post_title LIKE '%[attacker's input]%'
UNION [attacker's injected SQL]
Attacker
│
▼
Submits a crafted search request
│
▼
WordPress passes the "s" parameter
│
▼
WP Ticket builds SQL query using concatenation
│
▼
Database executes injected SQL
│
▼
Sensitive database information may be disclosed
普通访客执行网站搜索:
GET /?s=printer
插件将 s 参数的值合并到搜索工单相关信息的 SQL 查询中。
由于插件直接将搜索值拼接到 SQL 语句中而不是使用参数化查询,因此特制的搜索请求可以改变预期的 SQL 逻辑。未经认证的攻击者可能利用此行为从 WordPress 数据库中检索敏感信息,例如用户名或其他存储的数据。确切结果取决于应用程序的配置和数据库权限。 现在,攻击者可以操纵 s 参数注入自己的 SQL。例如,他们可以输入:
' UNION SELECT user_login, user_pass FROM wp_users -- -
这将使最终查询变成如下形式:
SELECT * FROM wp_posts WHERE post_title LIKE '%' UNION SELECT user_login, user_pass FROM wp_users -- -%'
成功利用可能允许攻击者:
| 指标 | 分数 |
|---|---|
| CVSS v3.1 (Wordfence CNA) | 7.5(高危) |
NVD 尚未发布自己的 CVSS 评估。
注意:厂商尚未发布完整的易受攻击实现。以下内容说明了易受攻击的编码模式。
$search = $query->query_vars['s'];
$sql = "
SELECT *
FROM tickets
WHERE title LIKE '%" . $search . "%'
";
$wpdb->get_results($sql);
SQL 语句是通过将用户可控输入直接拼接到查询字符串中来构建的。由于该输入未经过参数化或转义,因此可以改变 SQL 语句的结构。
$search = $query->query_vars['s'];
$sql = $wpdb->prepare(
"SELECT *
FROM tickets
WHERE title LIKE %s",
'%' . $search . '%'
);
$wpdb->get_results($sql);
使用 $wpdb->prepare() 可以将 SQL 语法与用户输入分离开来。数据库会将搜索值视为数据,而不是可执行的 SQL,从而防止攻击者修改查询结构。WP Ticket 6.0.5 中的官方修复用正确参数化的实现替代了易受攻击的查询构建方式。