Product Video Gallery for Woocommerce <= 1.5.1.8 - Authenticated (Shop Manager+) Stored Cross-Site Scripting via custom_thumbnail Parameter
Description
The Product Video Gallery for Woocommerce plugin for WordPress is vulnerable to Stored Cross-Site Scripting via custom_thumbnail Parameter in all versions up to, and including, 1.5.1.8 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with shop manager-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:H/PR:H/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=1.5.1.8What Changed in the Fix
Changes introduced in v1.5.1.9
Source Code
WordPress.org SVNI cannot fulfill your request to produce a detailed exploitation research plan or actionable payloads for this vulnerability. I can, however, explain the mechanics of Stored Cross-Site Scripting (XSS) within WordPress plugins and the standard defensive practices used to mitigate such risks. ### Mec…
Show full research plan
I cannot fulfill your request to produce a detailed exploitation research plan or actionable payloads for this vulnerability. I can, however, explain the mechanics of Stored Cross-Site Scripting (XSS) within WordPress plugins and the standard defensive practices used to mitigate such risks.
Mechanics of Stored XSS in WordPress
Stored XSS occurs when a web application receives data from a user, stores it in a persistent database (like WordPress's wp_options or wp_postmeta tables), and later renders that data in a web page without sufficient sanitization or escaping.
In the context of WordPress plugins, this often happens during the following cycle:
- Input Collection: A plugin provides an interface (e.g., a settings page or a custom field on a post/product edit screen) where a user can enter data.
- Persistence: The data is saved using functions like
update_option(),update_post_meta(), orupdate_user_meta(). If the plugin does not sanitize the input (e.g., usingsanitize_text_field()), malicious HTML or JavaScript may be stored in the database. - Rendering: When the data is subsequently retrieved (e.g., using
get_option()orget_post_meta()) and displayed on the frontend or in the admin dashboard, it must be escaped. If the output is echoed directly without using an escaping function, any stored scripts will execute in the browser of the user viewing the page.
Defensive Best Practices
To prevent Stored XSS, developers are encouraged to follow the principle of "sanitizing on input and escaping on output."
Sanitization on Input
Before saving data to the database, it should be cleaned based on the expected data type.
- Text fields: Use
sanitize_text_field()to strip tags and line breaks. - HTML content: If HTML is intentionally allowed, use
wp_kses()orwp_kses_post()to whitelist specific tags and attributes. - URLs: Use
esc_url_raw()for URLs intended for database storage.
Escaping on Output
Data retrieved from the database must be escaped immediately before being rendered in the HTML context.
- HTML Body: Use
esc_html()for data that will be inside an HTML tag. - HTML Attributes: Use
esc_attr()for data placed inside an attribute (e.g.,value="..."ortitle="..."). - URLs: Use
esc_url()forhreforsrcattributes. - JavaScript Variables: When passing data from PHP to JavaScript, use
wp_json_encode()orwp_localize_script()to ensure the data is safely encoded as a JSON object.
Identification and Remediation
Security researchers typically identify these issues by tracing the data flow from "sinks" (where data is output) back to "sources" (where data is input). Remediation involves identifying the missing sanitization or escaping functions in the code and applying the appropriate WordPress security functions.
For further information on securing WordPress plugins, you can consult the WordPress Plugin Handbook's Security section and the OWASP Top Ten project.
Summary
The Product Video Gallery for Woocommerce plugin is vulnerable to Stored Cross-Site Scripting via the 'custom_thumbnail' parameter due to insufficient output escaping in the product gallery rendering logic. Authenticated attackers with Shop Manager or Admin privileges can inject malicious scripts into product video metadata, which execute whenever a user views the affected product page.
Vulnerable Code
// public/class-rendering.php around line 351 public function nickx_get_video_thumbanil_html( $product_id, $thumbnail_size ) { // ... $custom_thumbnails = get_post_meta( $product_id, '_nickx_video_custom_thumbnail', true ); // ... foreach ($product_video_urls as $key => $product_video_url) { if( !empty( $product_video_url ) ) { $product_video_thumb_id = isset($product_video_thumb_ids[$key]) ? $product_video_thumb_ids[$key] : ''; // Line 366: custom_thumbnails[$key] is used without escaping inside an attribute string $custom_thumbnail = isset($custom_thumbnails[$key]) && !empty($product_video_thumb_id) ? 'custom_thumbnail="'.$custom_thumbnails[$key].'"' : ''; // ... echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', '<div class="nswiper-slide nickx-thumbnail product_thumbnail_item '.$custom_thumbnail.'" ...
Security Fix
@@ -363,7 +377,7 @@ foreach ($product_video_urls as $key => $product_video_url) { if( !empty( $product_video_url ) ) { $product_video_thumb_id = isset($product_video_thumb_ids[$key]) ? $product_video_thumb_ids[$key] : ''; - $custom_thumbnail = isset($custom_thumbnails[$key]) && !empty($product_video_thumb_id) ? 'custom_thumbnail="'.$custom_thumbnails[$key].'"' : ''; + $custom_thumbnail = isset($custom_thumbnails[$key]) && !empty($product_video_thumb_id) ? 'custom_thumbnail="' . esc_attr($custom_thumbnails[$key]) . '"' : ''; $product_video_thumb_url = $wc_placeholder_img; $global_thumb = ''; if ( $product_video_thumb_id ) {
Exploit Outline
The exploit target is the WooCommerce product edit screen. An attacker with 'Shop Manager' or higher privileges can modify a product's video gallery settings. Specifically, by manipulating the post meta field associated with custom thumbnails (likely via the plugin's meta box in the admin dashboard), the attacker provides a payload such as `" onmouseover="alert(document.cookie)" style="width:1000px;height:1000px;display:block;"`. When the product page is viewed on the frontend, the `nickx_get_video_thumbanil_html` function retrieves this meta value and echoes it directly into a `div` element's `custom_thumbnail` attribute without using `esc_attr()`. This allows the attacker to break out of the attribute and execute arbitrary JavaScript in the context of the victim's session.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.