Link Whisper Free <= 0.8.8 - Reflected Cross-Site Scripting
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:NTechnical Details
<=0.8.8Source Code
WordPress.org SVNThis 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-whisperorlink-whisper-reports(inferred from plugin functionality). - Vulnerable Parameter:
keyword,s, orfilter_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)
- Entry Point: An administrator accesses a plugin report page via a
GETrequest:wp-admin/admin.php?page=link-whisper-reports&keyword=<payload>. - Hook Registration: The plugin registers its admin menu via
add_menu_pageoradd_submenu_pagein a class likely namedWpLinkWhisperorLinkWhisper_Admin. - Data Retrieval: The callback function for the page (e.g.,
render_reports_page) retrieves the filter value directly from the superglobal:$keyword = $_GET['keyword'];. - Vulnerable Sink: The value of
$keywordis included in the HTML output, often within a "Search results for..." message or as thevalueattribute 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?.nonceor similar. - Strategy:
- Create a page with the Link Whisper shortcode (if applicable) or navigate to the Link Whisper dashboard.
- Use
browser_evalto inspect thewindowobject 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:
- Identify the Reflection Point: Send a probe request with a unique string (e.g.,
linkwhisper_probe) to candidate parameters. - 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>
- If inside an attribute:
- Execute Request: Use the
http_requesttool 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).
- URL:
6. Test Data Setup
- Install Plugin: Install Link Whisper Free version 0.8.8.
- 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 - 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
- Manual Check: Search the HTML response for the payload.
# Conceptually: grep -F "<script>alert(1)</script>" response.html - Version Comparison: Update to version 0.8.9 and repeat the request. The payload should now be escaped (e.g.,
"><script>).
9. Alternative Approaches
If the keyword parameter is not the sink:
- Check Table Pagination: Test the
orderbyandorderparameters in the link report tables. - Check Filter Status: Test parameters like
filter_statusorcategory_filter. - Check Tab Parameters: Some WordPress plugins reflect the current active "tab" in the URL without escaping:
?page=link-whisper&tab=<script>....
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
@@ -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.