Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-4406 — The Gravity Forms plugin for WordPress (tested through version 2.9.28) is vulnerable to unauthenticated reflected cross-site scripting (XSS) via the `form_ids` parameter in the `gform_get_config` AJAX action. | Kitploit
Tools/GitHubGitHub/hann1bl3l3ct3r/cve-2026-4406
Vulnerability AnalysisExploitationWeb Application ExploitationWeb SecurityPenetration Testing
GitHubhann1bl3l3ct3r/cve-2026-4406

CVE-2026-4406

The Gravity Forms plugin for WordPress (tested through version 2.9.28) is vulnerable to unauthenticated reflected cross-site scripting (XSS) via the `form_ids` parameter in the `gform_get_config` AJAX action.

View Repository
196 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

Gravity Forms <= 2.9.28 — Unauthenticated Reflected Cross-Site Scripting via gform_get_config form_ids Parameter

Vulnerability Summary

FieldValue
Affected SoftwareGravity Forms (WordPress Plugin)
VendorRocketgenius, Inc.
Vulnerability TypeCWE-79: Improper Neutralization of Input During Web Page Generation (Reflected Cross-Site Scripting)
CWE ChainCWE-20 → CWE-116 → CWE-838 → CWE-79 (see CWE Analysis below)
Affected VersionsConfirmed on 2.9.28 (latest as of discovery); earlier versions likely affected
Fixed Version2.9.30.1 (hotfix)
CVSS 3.1 Score6.1 (Medium)
CVSS 3.1 VectorAV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
Authentication RequiredNone (Unauthenticated)
User InteractionRequired (victim must visit attacker-controlled page or click crafted link)
Discovered ByAnthony Cihan — Obviam
Discovery Date2026-03-04
Disclosure Date2026-03-18
CVE IDCVE-2026-4406

Wordfence Public Record


Description

The Gravity Forms plugin for WordPress (tested through version 2.9.28) is vulnerable to unauthenticated reflected cross-site scripting (XSS) via the form_ids parameter in the gform_get_config AJAX action. The vulnerability exists because user-supplied form_ids values are reflected verbatim in the server's HTTP response without any sanitization, encoding, or output escaping. The response is served with a Content-Type: text/html; charset=UTF-8 header, which causes the browser to parse and render the reflected content as HTML, including any injected script elements.

An unauthenticated attacker can exploit this vulnerability to execute arbitrary JavaScript in the context of the target WordPress site's origin. Because the gform_get_config action requires a valid config_nonce, and this nonce is publicly embedded in the HTML source of every page that loads a Gravity Forms form, an attacker can trivially obtain a valid nonce by requesting any public-facing page on the target site before constructing the exploit request.

Successful exploitation allows an attacker to steal session cookies, perform actions on behalf of authenticated users (including WordPress administrators), redirect users to malicious sites, deface page content, or establish persistent access through administrative account creation.


Root Cause Analysis

Vulnerable Endpoint

POST /wp-admin/admin-ajax.php

Vulnerable Action

gform_get_config

Vulnerable Parameter

The args POST parameter accepts a JSON object containing a form_ids array. Values in this array are used as object keys in the JSON response structure without sanitization:

{"form_ids":["ATTACKER_CONTROLLED_VALUE"]}

Response Behavior

The server processes the form_ids values and reflects them as JSON keys inside the response body. The response is wrapped in HTML comment markers and served as 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 -->

Why This Is Exploitable

  1. No Input Validation: The form_ids values are not validated as integers, sanitized, or filtered. The server accepts arbitrary string content including HTML tags and event handlers.
  2. No Output Encoding: The form_ids values are reflected in the response body without HTML entity encoding. Characters such as <, >, ", and ' pass through unmodified.
  3. HTML Content-Type: The response is served with Content-Type: text/html; charset=UTF-8, which instructs the browser to parse the response body as HTML. Any HTML tags within the reflected value are instantiated and rendered by the browser's HTML parser.
  4. Publicly Accessible Nonce: The config_nonce required by the gform_get_config action is embedded in the JavaScript configuration object (gform_theme_config) on every page that loads a Gravity Forms form. This nonce is identical across all pages and is not bound to a specific user session, making it trivially obtainable by unauthenticated users.

CWE Analysis

This vulnerability is the result of multiple contributing weaknesses that chain together to produce the exploitable condition. While CWE-79 is the primary classification for CVE reporting purposes, the full chain documents how each failure compounds to enable exploitation.

Weakness Chain

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

CWE-20: Improper Input Validation (Contributing)

Role: Root enabler — allows malicious data to enter the processing pipeline.

The form_ids parameter in the args JSON object is expected to contain numeric form identifiers but accepts arbitrary string input without any validation. No type checking (intval()), no regex filtering (^[0-9]+$), no whitelist comparison against known form IDs, and no length restrictions are applied.

Evidence: The server accepts and processes form_ids values containing HTML tags, JavaScript event handlers, and arbitrary Unicode without rejection.

{"form_ids":["<svg onload=alert(1)>"]}    ← Accepted
{"form_ids":["3"]}                         ← Expected

CWE-116: Improper Encoding or Escaping of Output (Primary Technical Failure)

Role: Core vulnerability — the direct cause of the XSS condition.

When the server constructs the JSON response containing the form_ids values, it does not apply HTML entity encoding to the output. Characters with special meaning in HTML (<, >, ", ', &) pass through unmodified into the response body. The PHP functions htmlspecialchars(), esc_html(), wp_json_encode() with JSON_HEX_TAG, or equivalent output encoding functions are not applied to the form_ids values before they are written into the response.

Evidence: The literal string <svg onload=alert(document.domain)> appears in the response body byte-for-byte identical to the input, rather than as &lt;svg onload=alert(document.domain)&gt;.

CWE-838: Inappropriate Encoding for Output Context (Compounding)

Role: Context escalation — transforms a data reflection issue into executable code injection.

The response body contains JSON-structured data but is served with Content-Type: text/html; charset=UTF-8. This Content-Type declaration instructs the browser's HTML parser to process the entire response body as an HTML document. If the response were served as application/json, the browser would render the response as plain text and no HTML parsing would occur — the injected tags would be displayed as literal text rather than instantiated as DOM elements.

Evidence:

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

The X-Content-Type-Options: nosniff header is present but irrelevant because the server is explicitly declaring text/html — there is no MIME type sniffing to prevent.

Download Tool