[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fglcr0Kv6k3NTH8jF51J2prwEU86Sl2CgOjIZgLGdN5c":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":27,"research_verified":28,"research_rounds_completed":29,"research_plan":30,"research_summary":31,"research_vulnerable_code":32,"research_fix_diff":33,"research_exploit_outline":34,"research_model_used":35,"research_started_at":36,"research_completed_at":37,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":28,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":28,"source_links":38},"CVE-2026-10104","product-video-gallery-for-woocommerce-authenticated-shop-manager-stored-cross-site-scripting-via-customthumbnail-paramet","Product Video Gallery for Woocommerce \u003C= 1.5.1.8 - Authenticated (Shop Manager+) Stored Cross-Site Scripting via custom_thumbnail Parameter","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.","product-video-gallery-slider-for-woocommerce",null,"\u003C=1.5.1.8","1.5.1.9","medium",4.4,"CVSS:3.1\u002FAV:N\u002FAC:H\u002FPR:H\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-07-01 20:06:37","2026-07-02 08:33:08",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff61885bc-b7da-42b8-a0d3-ba5d7d19b536?source=api-prod",1,[22,23,24,25,26],"admin\u002Fclass-setting.php","product-video-gallery-slider-for-woocommerce.php","public\u002Fclass-rendering.php","public\u002Fjs\u002Fnickx.front.js","readme.txt","researched",false,3,"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.\n\n### Mechanics of Stored XSS in WordPress\n\nStored 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.\n\nIn the context of WordPress plugins, this often happens during the following cycle:\n\n1.  **Input Collection:** A plugin provides an interface (e.g., a settings page or a custom field on a post\u002Fproduct edit screen) where a user can enter data.\n2.  **Persistence:** The data is saved using functions like `update_option()`, `update_post_meta()`, or `update_user_meta()`. If the plugin does not sanitize the input (e.g., using `sanitize_text_field()`), malicious HTML or JavaScript may be stored in the database.\n3.  **Rendering:** When the data is subsequently retrieved (e.g., using `get_option()` or `get_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.\n\n### Defensive Best Practices\n\nTo prevent Stored XSS, developers are encouraged to follow the principle of \"sanitizing on input and escaping on output.\"\n\n#### Sanitization on Input\nBefore saving data to the database, it should be cleaned based on the expected data type.\n*   **Text fields:** Use `sanitize_text_field()` to strip tags and line breaks.\n*   **HTML content:** If HTML is intentionally allowed, use `wp_kses()` or `wp_kses_post()` to whitelist specific tags and attributes.\n*   **URLs:** Use `esc_url_raw()` for URLs intended for database storage.\n\n#### Escaping on Output\nData retrieved from the database must be escaped immediately before being rendered in the HTML context.\n*   **HTML Body:** Use `esc_html()` for data that will be inside an HTML tag.\n*   **HTML Attributes:** Use `esc_attr()` for data placed inside an attribute (e.g., `value=\"...\"` or `title=\"...\"`).\n*   **URLs:** Use `esc_url()` for `href` or `src` attributes.\n*   **JavaScript Variables:** When passing data from PHP to JavaScript, use `wp_json_encode()` or `wp_localize_script()` to ensure the data is safely encoded as a JSON object.\n\n### Identification and Remediation\nSecurity 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.\n\nFor further information on securing WordPress plugins, you can consult the [WordPress Plugin Handbook's Security section](https:\u002F\u002Fdeveloper.wordpress.org\u002Fplugins\u002Fsecurity\u002F) and the [OWASP Top Ten](https:\u002F\u002Fowasp.org\u002Fwww-project-top-ten\u002F) project.","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.","\u002F\u002F public\u002Fclass-rendering.php around line 351\npublic function nickx_get_video_thumbanil_html( $product_id, $thumbnail_size ) {\n    \u002F\u002F ...\n    $custom_thumbnails      = get_post_meta( $product_id, '_nickx_video_custom_thumbnail', true );\n    \u002F\u002F ...\n    foreach ($product_video_urls as $key => $product_video_url) {\n        if( !empty( $product_video_url ) ) {\n            $product_video_thumb_id   = isset($product_video_thumb_ids[$key]) ? $product_video_thumb_ids[$key] : '';\n            \u002F\u002F Line 366: custom_thumbnails[$key] is used without escaping inside an attribute string\n            $custom_thumbnail        = isset($custom_thumbnails[$key]) && !empty($product_video_thumb_id) ? 'custom_thumbnail=\"'.$custom_thumbnails[$key].'\"' : '';\n            \u002F\u002F ...\n            echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', '\u003Cdiv class=\"nswiper-slide nickx-thumbnail product_thumbnail_item '.$custom_thumbnail.'\" ...","--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fproduct-video-gallery-slider-for-woocommerce\u002F1.5.1.8\u002Fpublic\u002Fclass-rendering.php\t2026-05-20 16:20:18.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fproduct-video-gallery-slider-for-woocommerce\u002F1.5.1.9\u002Fpublic\u002Fclass-rendering.php\t2026-06-30 15:59:08.000000000 +0000\n@@ -363,7 +377,7 @@\n \t\t\t\t\tforeach ($product_video_urls as $key => $product_video_url) {\n \t\t\t\t\t\tif( !empty( $product_video_url ) ) {\n \t\t\t\t\t\t\t$product_video_thumb_id   = isset($product_video_thumb_ids[$key]) ? $product_video_thumb_ids[$key] : '';\n-\t\t\t\t\t\t\t$custom_thumbnail        = isset($custom_thumbnails[$key]) && !empty($product_video_thumb_id) ? 'custom_thumbnail=\"'.$custom_thumbnails[$key].'\"' : '';\n+\t\t\t\t\t\t\t$custom_thumbnail        = isset($custom_thumbnails[$key]) && !empty($product_video_thumb_id) ? 'custom_thumbnail=\"' . esc_attr($custom_thumbnails[$key]) . '\"' : '';\n \t\t\t\t\t\t\t$product_video_thumb_url = $wc_placeholder_img;\n \t\t\t\t\t\t\t$global_thumb = '';\n \t\t\t\t\t\t\tif ( $product_video_thumb_id ) {","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.","gemini-3-flash-preview","2026-07-25 11:12:29","2026-07-25 11:13:01",{"type":39,"vulnerable_version":40,"fixed_version":11,"vulnerable_browse":41,"vulnerable_zip":42,"fixed_browse":43,"fixed_zip":44,"all_tags":45},"plugin","1.5.1.8","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fproduct-video-gallery-slider-for-woocommerce\u002Ftags\u002F1.5.1.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fproduct-video-gallery-slider-for-woocommerce.1.5.1.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fproduct-video-gallery-slider-for-woocommerce\u002Ftags\u002F1.5.1.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fproduct-video-gallery-slider-for-woocommerce.1.5.1.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fproduct-video-gallery-slider-for-woocommerce\u002Ftags"]