CVE-2026-1755

Menu Icons by ThemeIsle <= 0.13.20 - Authenticated (Author+) Stored Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
0.13.21
Patched in
1d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=0.13.20
PublishedFebruary 3, 2026
Last updatedFebruary 3, 2026
Affected pluginmenu-icons

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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_posts and upload_files capabilities required to modify attachment metadata.
  • Preconditions:
    1. The plugin "Menu Icons" must be active.
    2. An image must be assigned as an icon to a menu item.
    3. The menu must be assigned to a location visible on the frontend.

3. Code Flow

  1. Storage: When an Author edits an attachment's "Alt Text" in the Media Library, WordPress saves the value to the _wp_attachment_image_alt meta key for that attachment ID.
  2. Assignment: The user goes to Appearance > Menus, selects a menu item, clicks "Select Icon", chooses the "Image" type, and selects the malicious attachment.
  3. Rendering (Sink):
    • The plugin hooks into the menu rendering process (likely via the wp_nav_menu_objects filter or a custom Walker class).
    • In the rendering logic for the "Image" icon type (likely located in includes/library/item.php or includes/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 $alt is not passed through esc_attr(), an attacker can break out of the alt attribute using "> and inject a <script> tag.

4. Nonce Acquisition Strategy

While the vulnerability itself is a Stored XSS in the output, the injection requires updating attachment metadata.

  1. For Attachment Update: To update the _wp_attachment_image_alt via post.php, a nonce named _wpnonce is required.
    • Method:
      1. Navigate to wp-admin/upload.php.
      2. Click on an attachment to open the "Edit Media" page (post.php?post=ID&action=edit).
      3. Use browser_eval to extract the nonce: document.querySelector('#_wpnonce').value.
  2. 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?.nonce or window.navMenuL10n.
    • Action: However, assigning the icon to the menu item is handled by the standard WordPress nav-menus.php save process, which uses the update-nav-menu nonce.

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

  1. User: Create a user with the Author role.
  2. Menu: Ensure at least one menu exists and is assigned to a theme location (e.g., "Primary").
  3. Post: Create a dummy page/post to add to the menu.
  4. Attachment: Upload a simple .jpg or .png image. Note the ATTACHMENT_ID.

7. Expected Results

  • The POST request to post.php should return a 302 redirect 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

  1. 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>.
  2. 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 the ATTACHMENT_ID.

9. Alternative Approaches

If updating via post.php is blocked or difficult to automate:

  1. Media AJAX Endpoint: Use the wp_ajax_save_attachment_compat action.
    • Body: action=save-attachment-compat&id=[ID]&nonce=[NONCE]&attachments[[ID]][alt]="><script>alert(1)</script>
  2. 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.
Research Findings
Static analysis — not yet PoC-verified

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

--- includes/type/image.php
+++ includes/type/image.php
@@ -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.