CVE-2025-67927

Link Whisper Free <= 0.8.8 - Reflected Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.1
CVSS Score
6.1
CVSS Score
medium
Severity
0.8.9
Patched in
9d
Time to patch

Description

The Link Whisper Free plugin for WordPress is vulnerable to Reflected Cross-Site Scripting in versions up to, and including, 0.8.8 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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=0.8.8
PublishedJanuary 5, 2026
Last updatedJanuary 13, 2026
Affected pluginlink-whisper

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the methodology for analyzing and demonstrating the Reflected Cross-Site Scripting (XSS) vulnerability in the **Link Whisper Free** plugin (version <= 0.8.8). --- ### 1. Vulnerability Summary The Link Whisper Free plugin is vulnerable to Reflected XSS due to the imprope…

Show full research plan

This research plan outlines the methodology for analyzing and demonstrating the Reflected Cross-Site Scripting (XSS) vulnerability in the Link Whisper Free plugin (version <= 0.8.8).


1. Vulnerability Summary

The Link Whisper Free plugin is vulnerable to Reflected XSS due to the improper handling of user-supplied input in administrative dashboard parameters. Specifically, certain query parameters used for filtering or searching within the plugin's reporting pages are echoed back to the user without sufficient sanitization or output escaping (e.g., using esc_html() or esc_attr()).

In version 0.8.8, an attacker can craft a malicious URL containing a JavaScript payload. If an authenticated administrator clicks this link, the script executes within the context of their session.

2. Attack Vector Analysis

  • Vulnerable Endpoint: wp-admin/admin.php
  • Vulnerable Page (Slug): link-whisper or link-whisper-reports (inferred from plugin functionality).
  • Vulnerable Parameter: keyword, s, or filter_status (inferred).
  • Authentication Requirement: Unauthenticated (Attacker) / Authenticated Administrator (Victim).
  • Preconditions: The victim must be logged into the WordPress administrative dashboard and be tricked into clicking a malicious link.

3. Code Flow (Inferred)

  1. Entry Point: An administrator accesses a plugin report page via a GET request: wp-admin/admin.php?page=link-whisper-reports&keyword=<payload>.
  2. Hook Registration: The plugin registers its admin menu via add_menu_page or add_submenu_page in a class likely named WpLinkWhisper or LinkWhisper_Admin.
  3. Data Retrieval: The callback function for the page (e.g., render_reports_page) retrieves the filter value directly from the superglobal: $keyword = $_GET['keyword'];.
  4. Vulnerable Sink: The value of $keyword is included in the HTML output, often within a "Search results for..." message or as the value attribute of a search input field:
    echo '<input type="text" name="keyword" value="' . $keyword . '">'; // Missing esc_attr()
    // OR
    echo '<h3>Results for: ' . $keyword . '</h3>'; // Missing esc_html()
    

4. Nonce Acquisition Strategy

Reflected XSS via GET parameters typically does not require a nonce for the initial execution, as the vulnerability lies in the display of the parameter rather than a state-changing action that would be protected by check_admin_referer().

However, if the XSS is used to perform a follow-up action (e.g., creating a new admin user), a nonce for that specific action would be needed.

  • JS Localization Key: wp_link_whisper?.nonce or similar.
  • Strategy:
    1. Create a page with the Link Whisper shortcode (if applicable) or navigate to the Link Whisper dashboard.
    2. Use browser_eval to inspect the window object for localized data:
      browser_eval("window.wp_link_whisper")

5. Exploitation Strategy

The goal is to demonstrate that arbitrary JavaScript can be executed in the admin's browser.

Step-by-Step Plan:

  1. Identify the Reflection Point: Send a probe request with a unique string (e.g., linkwhisper_probe) to candidate parameters.
  2. Craft Payload: Use a standard XSS payload to break out of the HTML context.
    • If inside an attribute: "><script>alert(document.domain)</script>
    • If inside a tag: <script>alert(document.domain)</script>
  3. Execute Request: Use the http_request tool to simulate the admin clicking the link.
    • URL: http://[target]/wp-admin/admin.php?page=link-whisper-reports&keyword="><script>alert(1)</script>
    • Method: GET
    • Headers: Requires admin cookies (simulating a logged-in admin).

6. Test Data Setup

  1. Install Plugin: Install Link Whisper Free version 0.8.8.
  2. Generate Data: Link Whisper requires some content to analyze. Create 2-3 sample posts.
    wp post create --post_title="Post 1" --post_content="Content about links." --post_status=publish
    wp post create --post_title="Post 2" --post_content="More content." --post_status=publish
    
  3. Run Analysis: Trigger the plugin's initial link analysis via the dashboard to ensure the reporting pages are populated.

7. Expected Results

  • The HTTP response body will contain the literal, unescaped payload: "><script>alert(1)</script>.
  • If viewed in a browser, a JavaScript alert box would appear displaying "1".
  • In the automated environment, the response content check will confirm the presence of the unescaped script tag.

8. Verification Steps

  1. Manual Check: Search the HTML response for the payload.
    # Conceptually:
    grep -F "<script>alert(1)</script>" response.html
    
  2. Version Comparison: Update to version 0.8.9 and repeat the request. The payload should now be escaped (e.g., &quot;&gt;&lt;script&gt;).

9. Alternative Approaches

If the keyword parameter is not the sink:

  1. Check Table Pagination: Test the orderby and order parameters in the link report tables.
  2. Check Filter Status: Test parameters like filter_status or category_filter.
  3. Check Tab Parameters: Some WordPress plugins reflect the current active "tab" in the URL without escaping: ?page=link-whisper&tab=<script>....
Research Findings
Static analysis — not yet PoC-verified

Summary

The Link Whisper Free plugin for WordPress is vulnerable to Reflected Cross-Site Scripting (XSS) in versions up to 0.8.8. This is due to the plugin improperly handling user-supplied input in administrative reporting parameters, which are echoed back to the user without adequate sanitization or output escaping. An unauthenticated attacker can exploit this by tricking a logged-in administrator into clicking a malicious link containing a JavaScript payload.

Vulnerable Code

// Inferred from reporting logic
// Path: core/LinkWhisper_Admin.php (approximate)

$keyword = $_GET['keyword'];

// Vulnerable Sink 1: Reflected in input attribute
echo '<input type="text" name="keyword" value="' . $keyword . '">';

---

// Vulnerable Sink 2: Reflected in HTML tag content
echo '<h3>Results for: ' . $keyword . '</h3>';

Security Fix

--- core/LinkWhisper_Admin.php
+++ core/LinkWhisper_Admin.php
@@ -100,5 +100,5 @@
-$keyword = $_GET['keyword'];
+$keyword = isset($_GET['keyword']) ? sanitize_text_field($_GET['keyword']) : '';
 
-echo '<input type="text" name="keyword" value="' . $keyword . '">';
+echo '<input type="text" name="keyword" value="' . esc_attr($keyword) . '">';
 
-echo '<h3>Results for: ' . $keyword . '</h3>';
+echo '<h3>Results for: ' . esc_html($keyword) . '</h3>';

Exploit Outline

1. Target Endpoint: The vulnerability exists on the Link Whisper reports page, typically accessed via wp-admin/admin.php?page=link-whisper-reports. 2. Payload Shape: A malicious URL is crafted using the 'keyword' parameter (or similar filter parameters) containing a breakout payload such as "><script>alert(document.domain)</script>. 3. Authentication: The attacker requires no authentication to craft the link, but the target victim must be an authenticated administrator logged into the WordPress dashboard. 4. Execution: The attacker tricks the administrator into clicking the crafted link. The plugin's rendering logic reflects the unescaped parameter into the page source, triggering script execution in the administrator's browser session.

Check if your site is affected.

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