NEX-Forms <= 9.1.7 - Reflected Cross-Site Scripting
Description
The NEX-Forms plugin for WordPress is vulnerable to Reflected Cross-Site Scripting in versions up to, and including, 9.1.7 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a link.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:NTechnical Details
<=9.1.7Source Code
WordPress.org SVNThis research plan focuses on identifying and exploiting a Reflected Cross-Site Scripting (XSS) vulnerability in the **NEX-Forms** plugin (<= 9.1.7). ### 1. Vulnerability Summary The NEX-Forms plugin fails to sufficiently sanitize or escape user-controlled input before reflecting it back into the H…
Show full research plan
This research plan focuses on identifying and exploiting a Reflected Cross-Site Scripting (XSS) vulnerability in the NEX-Forms plugin (<= 9.1.7).
1. Vulnerability Summary
The NEX-Forms plugin fails to sufficiently sanitize or escape user-controlled input before reflecting it back into the HTML response. This vulnerability typically occurs in parameters used for form previews, administration tabs, or AJAX-driven content updates. Since it is a Reflected XSS, the payload is not stored in the database but is instead executed immediately when a victim clicks a specially crafted link containing the malicious script.
2. Attack Vector Analysis
- Vulnerable Endpoint: Likely
wp-admin/admin.php(if targeting admins) or a frontend page containing a NEX-Forms shortcode (if targeting general users). - Vulnerable Parameters (Inferred): Likely candidates in NEX-Forms are
nexus,nex_forms_admin_page,page_id, orform_id. - Authentication Level: Unauthenticated (as per CVSS vector
PR:N). - Preconditions: A victim must be tricked into clicking a URL. If the XSS triggers in the admin dashboard, an authenticated administrator session is required for high-impact exploitation (e.g., account takeover).
3. Code Flow (Inferred)
Based on the architecture of NEX-Forms, the execution flow likely follows this path:
- Entry Point: An
initorwp_loadedhook is registered in the main plugin file (e.g.,nex-forms.php). - Input Acquisition: The plugin retrieves a parameter directly from
$_GETor$_REQUEST. - Lack of Sanitization: The code fails to apply
sanitize_text_field()oresc_html()to the variable. - Sink: The raw variable is echoed into the page, often inside a
value=""attribute, a<script>block, or as part of a UI message.- Search Pattern:
grep -rP "echo.*\\\$_GET\['(nexus|nex_forms|page_id)'\]" .
- Search Pattern:
4. Nonce Acquisition Strategy (Inferred)
While reflected XSS often doesn't require a nonce (as it occurs during GET requests), if the reflection occurs within an AJAX handler (via admin-ajax.php), a nonce may be required.
Strategy for NEX-Forms:
- Identify Shortcode: NEX-Forms uses
[nex_forms id="<ID>"]. - Create Test Page:
wp post create --post_type=page --post_title="XSS Test" --post_status=publish --post_content='[nex_forms id="1"]' - Extract Nonce via Browser:
- Navigate to the newly created page.
- NEX-Forms typically localizes script parameters in a variable named
nex_forms_scripts_paramsornf_ajax_object. - Execution Command:
browser_eval("window.nex_forms_scripts_params?.nex_forms_ajax_nonce")orbrowser_eval("window.nf_ajax_object?.nonce").
5. Exploitation Strategy
The goal is to demonstrate that arbitrary JavaScript can be executed.
Step 1: Discovery
Scan the plugin for unescaped reflections:
grep -rn "echo \$_GET" wp-content/plugins/nex-forms-express-wp-form-builder/
Step 2: Craft Payload
If a parameter like nexus is reflected:
- Simple Payload:
<script>alert(document.domain)</script> - Attribute Breakout:
"><script>alert(1)</script>
Step 3: Execute Request
Using the http_request tool, simulate a victim clicking the link.
- Method:
GET - URL:
http://localhost:8080/?nexus=<script>alert(1)</script>(Adjust parameter based on Discovery step). - Headers:
Content-Type: text/html
6. Test Data Setup
- Install NEX-Forms: Ensure version 9.1.7 is active.
- Create a Form: Use WP-CLI or the UI to create at least one form so that shortcodes are valid.
# (Optional) Use WP-CLI to ensure a form exists if the plugin supports it - Target Page: Create a public page with the NEX-Forms shortcode to ensure all plugin JS/CSS and potential reflection points are active.
7. Expected Results
- The HTTP response body should contain the literal string
<script>alert(1)</script>(or the chosen canary). - If using
browser_navigate, the browser should trigger an alert dialog or a console log. - The source code of the rendered page should show the payload unescaped (e.g.,
<div class="..."><script>alert(1)</script></div>).
8. Verification Steps
- Search Response: Use
grepor string matching on thehttp_requestoutput to find the payload.Expected: ...Results for: <script>alert(1)</script>...
- Check for Escaping: Confirm that characters like
<and>were NOT converted to<and>.
9. Alternative Approaches
If the reflection is inside a JavaScript block (DOM-based or reflected into JS), the payload needs to break out of the JS string:
- Payload:
';alert(1);// - Sink Investigation: Look for
wp_localize_scriptcalls inincludes/class-nex-forms.php(inferred) that pass$_GETparameters withoutesc_js().
If the reflection is in the Admin Dashboard:
- Target URL:
http://localhost:8080/wp-admin/admin.php?page=nex-forms-dash&nexus=<script>alert(1)</script> - Requirement: The
http_requestmust include admin cookies.
Summary
The NEX-Forms plugin for WordPress is vulnerable to Reflected Cross-Site Scripting (XSS) in versions up to 9.1.7. This occurs because the plugin reflects user-controlled input from GET parameters directly into the HTML response without adequate sanitization or output escaping, allowing execution of arbitrary scripts.
Exploit Outline
1. Identify a vulnerable GET parameter (likely 'nexus' or 'nex_forms_admin_page') used by the plugin in administrative or frontend contexts. 2. Craft a malicious URL containing a JavaScript payload in the identified parameter, such as: http://example.com/wp-admin/admin.php?page=nex-forms-dash&nexus=<script>alert(document.domain)</script>. 3. Trick an authenticated user (ideally an administrator) into clicking the link. 4. Upon interaction, the browser executes the injected script within the context of the user's session, which could lead to session hijacking or unauthorized administrative actions. 5. Unauthenticated attackers can create these links, but they require a victim to click them to execute.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.