Atomic Edge analysis of CVE-2026-1755:
This vulnerability is an authenticated stored cross-site scripting (XSS) flaw in the Menu Icons by ThemeIsle WordPress plugin, affecting versions up to and including 0.13.20. The vulnerability exists in the plugin’s front-end icon rendering function, allowing attackers with Author-level access or higher to inject malicious scripts that execute when a user views a compromised page. The CVSS score of 6.4 reflects the need for authentication and the Author+ privilege level.
The root cause is insufficient output escaping of the image alt text attribute within the plugin’s HTML generation. The vulnerable code resides in the `menu-icons/includes/front.php` file at line 494. The `$image_alt` variable, which contains the value of the `_wp_attachment_image_alt` post meta field, is directly concatenated into an HTML `
` tag without proper escaping. The variables `$width`, `$height`, and `$style` also lacked escaping. This lack of output escaping allows arbitrary script content to be injected into the page DOM.
Exploitation requires an authenticated attacker with at least Author-level permissions. The attacker would edit or create a menu item using the plugin’s functionality, setting a malicious payload in the image alt text field (the `_wp_attachment_image_alt` post meta). A typical payload would be an attribute escape sequence like `” onload=”alert(‘XSS’)”`. When the plugin renders the menu icon on the front-end, the unescaped alt text is output, causing the browser to execute the injected JavaScript in the context of any user viewing that page.
The patch, implemented in version 0.13.21, adds proper output escaping to all dynamic variables inserted into the HTML image tag. The diff shows the addition of `esc_attr()` function calls to the `$image_alt`, `$width`, `$height`, and `$style` variables on line 494 of `menu-icons/includes/front.php`. The `esc_attr()` WordPress function encodes special characters for safe use within HTML attributes, neutralizing any script content. The version numbers in `menu-icons.php` and `composer/installed.php` were updated to reflect the patched release.
Successful exploitation leads to stored XSS, where malicious JavaScript executes in the browser of any user who visits a page containing the compromised menu icon. This can result in session hijacking, account takeover, defacement, or redirection to malicious sites. Attackers could perform actions on behalf of the victim user, potentially escalating privileges if the victim has administrative access.
--- a/menu-icons/includes/front.php
+++ b/menu-icons/includes/front.php
@@ -494,10 +494,10 @@
'<img src="%s" class="%s" aria-hidden="true" alt="%s"%s%s%s/>',
esc_url( wp_get_attachment_url( $meta['icon'] ) ),
esc_attr( $classes ),
- $image_alt,
- $width,
- $height,
- $style
+ esc_attr( $image_alt ),
+ esc_attr( $width ),
+ esc_attr( $height ),
+ esc_attr( $style )
);
}
--- a/menu-icons/menu-icons.php
+++ b/menu-icons/menu-icons.php
@@ -11,7 +11,7 @@
* Plugin name: Menu Icons
* Plugin URI: https://github.com/Codeinwp/wp-menu-icons
* Description: Spice up your navigation menus with pretty icons, easily.
- * Version: 0.13.20
+ * Version: 0.13.21
* Author: ThemeIsle
* Author URI: https://themeisle.com
* License: GPLv2
@@ -29,7 +29,7 @@
const DISMISS_NOTICE = 'menu-icons-dismiss-notice';
- const VERSION = '0.13.20';
+ const VERSION = '0.13.21';
/**
* Holds plugin data
--- a/menu-icons/vendor/composer/installed.php
+++ b/menu-icons/vendor/composer/installed.php
@@ -1,9 +1,9 @@
<?php return array(
'root' => array(
'name' => 'codeinwp/wp-menu-icons',
- 'pretty_version' => 'v0.13.20',
- 'version' => '0.13.20.0',
- 'reference' => '0cbd7e1de60535afb7e876ad0f1c470fdea73af7',
+ 'pretty_version' => 'v0.13.21',
+ 'version' => '0.13.21.0',
+ 'reference' => 'f9b473210afd7b11edf9106fa8665f910d30c98f',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -49,9 +49,9 @@
'dev_requirement' => false,
),
'codeinwp/wp-menu-icons' => array(
- 'pretty_version' => 'v0.13.20',
- 'version' => '0.13.20.0',
- 'reference' => '0cbd7e1de60535afb7e876ad0f1c470fdea73af7',
+ 'pretty_version' => 'v0.13.21',
+ 'version' => '0.13.21.0',
+ 'reference' => 'f9b473210afd7b11edf9106fa8665f910d30c98f',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
// ==========================================================================
// 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
// CVE-2026-1755 - Menu Icons by ThemeIsle <= 0.13.20 - Authenticated (Author+) Stored Cross-Site Scripting
<?php
// CONFIGURATION
$target_url = 'http://vulnerable-wordpress-site.com';
$username = 'author_user';
$password = 'author_pass';
$payload = '" onload="alert(`Atomic Edge XSS`)"';
// Initialize cURL session for WordPress login
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => '1'
)));
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$login_result = curl_exec($ch);
// Check if login succeeded by looking for admin dashboard indicators
if (strpos($login_result, 'Dashboard') === false && strpos($login_result, 'wp-admin') === false) {
die('Login failed. Check credentials.');
}
// The attack vector requires manipulating the '_wp_attachment_image_alt' meta for a menu item.
// This typically involves a multi-step process: creating/editing a nav menu item via admin-ajax.php.
// The exact AJAX action and parameters depend on the plugin's admin interface flow.
// Due to the complexity of simulating the full WordPress menu editor UI and nonce handling,
// a direct, reliable PoC script for stored XSS via this specific meta field is not feasible
// without reverse-engineering the plugin's private AJAX handlers and menu update logic.
// Therefore, returning null as per instructions for cases where a meaningful PoC cannot be produced.
?>