[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fNqBHW5k7UqceaHt9UQcnse-ojA29HOgjeDrYoo6K9Rg":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-9134","photo-gallery-by-foogallery-responsive-image-gallery-masonry-gallery-carousel-authenticated-contributor-stored-cross-sit","Photo Gallery by FooGallery : Responsive Image Gallery, Masonry Gallery & Carousel \u003C= 3.1.31 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'custom_attribute_key' Shortcode Parameter","The FooGallery plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'custom_attribute_key' shortcode parameter in versions up to, and including, 3.1.31 This is due to an incomplete JavaScript event handler blacklist in the foogallery_sanitize_javascript() function, which blocks only a subset of HTML event attributes (onmouseover, onmouseout, onpointerenter, onclick, onload, onchange, onerror) while permitting others such as 'onmouseenter', combined with the failure to escape the attribute key when building the gallery container HTML in foogallery_build_container_attributes_safe(). 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.","foogallery",null,"\u003C=3.1.31","3.1.32","medium",6.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-06-12 18:03:23","2026-06-13 06:48:00",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fdd9650e6-7c3c-4510-9749-a3503924855f?source=api-prod",1,[22,23,24,25,26,27,28,29],"README.txt","foogallery.php","includes\u002Fadmin\u002Fclass-gallery-metabox-fields.php","includes\u002Fadmin\u002Fview-help-pro.php","includes\u002Fclass-gallery-advanced-settings.php","includes\u002Fclass-override-thumbnail.php","includes\u002Fextensions\u002Fclass-extensions-api.php","includes\u002Fextensions\u002Fclass-extensions-loader.php","researched",false,3,"# Research Plan: CVE-2026-9134 - FooGallery Stored XSS\n\n## 1. Vulnerability Summary\nThe **Gallery by FooGallery** plugin is vulnerable to **Stored Cross-Site Scripting (XSS)** via the `custom_attribute_key` shortcode parameter in versions up to 3.1.31. The vulnerability stems from two failures:\n1.  **Incomplete Blacklist:** The `foogallery_sanitize_javascript()` function (likely in `includes\u002Ffunctions.php`) uses an incomplete blacklist of JavaScript event handlers. While it blocks common events like `onclick` or `onload`, it permits others like `onmouseenter`.\n2.  **Unescaped Attribute Keys:** The function responsible for rendering the gallery container HTML, `foogallery_build_container_attributes_safe()`, fails to escape or properly validate the attribute keys before echoing them into the `\u003Cdiv>` container.\n\nAn authenticated attacker with **Contributor+** privileges can use a shortcode with a malicious `custom_attribute_key` (e.g., `onmouseenter`) and a corresponding `custom_attribute_value` (e.g., `alert(1)`) to inject arbitrary JavaScript into pages.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** WordPress Post\u002FPage Editor (via Shortcode) or FooGallery Settings.\n*   **Shortcode:** `[foogallery]`\n*   **Vulnerable Parameters:** `custom_attribute_key` and `custom_attribute_value`.\n*   **Authentication:** Contributor level or higher (required to save posts containing shortcodes or to edit gallery objects).\n*   **Precondition:** A FooGallery must exist (or be created) to provide a base `id` for the shortcode.\n\n## 3. Code Flow\n1.  **Shortcode Parsing:** When a post containing `[foogallery id=\"123\" custom_attribute_key=\"...\" ...]` is viewed, the shortcode handler is triggered.\n2.  **Setting Retrieval:** The plugin calls `foogallery_gallery_template_setting()` to retrieve settings. This function prioritizes shortcode attributes over stored gallery settings.\n3.  **Attribute Processing:** In `includes\u002Fclass-gallery-advanced-settings.php`, the `add_container_attributes()` function is called via the `foogallery_build_container_attributes` filter.\n    *   `$custom_attribute_key` is fetched and passed through `sanitize_title()`.\n    *   `$custom_attribute_value` is fetched and passed through `sanitize_text_field()`.\n    *   Both are passed to `foogallery_sanitize_javascript()` (the flawed blacklist).\n    *   The key and value are added to the `$attributes` array: `$attributes[$custom_attribute_key] = $custom_attribute_value;`\n4.  **HTML Generation:** The `$attributes` array is passed to `foogallery_build_container_attributes_safe()`. This function iterates","The FooGallery plugin is vulnerable to Stored Cross-Site Scripting via gallery custom attributes because it uses an incomplete blacklist for JavaScript event handlers and fails to properly escape attribute keys. This allows authenticated users with Contributor-level access and above to inject malicious scripts into galleries that execute when other users view the gallery.","\u002F* File: includes\u002Fclass-gallery-advanced-settings.php (~line 148) *\u002F\n\t\tfunction add_container_attributes( $attributes, $gallery ) {\n\t\t\tglobal $current_foogallery;\n\n\t\t\tif ( $current_foogallery === $gallery ) {\n                $custom_attribute_key = sanitize_title( foogallery_gallery_template_setting( 'custom_attribute_key', '' ) );\n                $custom_attribute_value = sanitize_text_field( foogallery_gallery_template_setting( 'custom_attribute_value', '' ) );\n\n                if ( !empty( $custom_attribute_key ) && !empty( $custom_attribute_value ) ) {\n\n                    \u002F\u002Fdo further cleaning!\n                    $custom_attribute_key = foogallery_sanitize_javascript( $custom_attribute_key );\n                    $custom_attribute_value = foogallery_sanitize_javascript( $custom_attribute_value );\n\n                    if ( !empty( $custom_attribute_key ) && !empty( $custom_attribute_value ) ) {\n                        $attributes[$custom_attribute_key] = $custom_attribute_value;\n                    }\n                }\n            }\n\n\t\t\treturn $attributes;\n\t\t}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Ffoogallery\u002F3.1.31\u002Fincludes\u002Fclass-gallery-advanced-settings.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Ffoogallery\u002F3.1.32\u002Fincludes\u002Fclass-gallery-advanced-settings.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Ffoogallery\u002F3.1.31\u002Fincludes\u002Fclass-gallery-advanced-settings.php\t2026-05-18 15:59:08.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Ffoogallery\u002F3.1.32\u002Fincludes\u002Fclass-gallery-advanced-settings.php\t2026-05-21 18:04:28.000000000 +0000\n@@ -16,6 +16,9 @@\n \t\t\t\u002F\u002Fadd custom attributes\n \t\t\tadd_filter( 'foogallery_build_container_attributes', array( $this, 'add_container_attributes' ), 10, 3 );\n \n+\t\t\t\u002F\u002Fsanitize custom attributes when gallery settings are saved\n+\t\t\tadd_filter( 'foogallery_save_gallery_settings', array( $this, 'save_custom_attribute_settings' ), 20, 3 );\n+\n \t\t\t\u002F\u002Fadd custom class to container\n \t\t\tadd_filter( 'foogallery_build_class_attribute', array( $this, 'add_custom_class' ), 10, 2 );\n \n@@ -62,22 +65,29 @@\n \t\t\t\t'default'  => '',\n \t\t\t);\n \n+\t\t\t$custom_attribute_disabled = ! current_user_can( 'manage_options' );\n+\t\t\t$custom_attribute_row_data = $custom_attribute_disabled ? array( 'data-foogallery-locked' => 'true' ) : array();\n+\n             $fields[] = array( chains\n                 'id'       => 'custom_attribute_key',\n                 'title'    => __( 'Custom Attribute Key', 'foogallery' ),\n-                'desc'     => __( 'Used in combination with \"Custom Attribute Value\" to add a custom attribute to the gallery container. To be used by developers only!', 'foogallery' ),\n+                'desc'     => __( 'Used in combination with \"Custom Attribute Value\" to add a custom attribute to the gallery container. Only administrators can edit this setting. To be used by developers only!', 'foogallery' ),\n                 'section'  => __( 'Advanced', 'foogallery' ),\n                 'type'     => 'text',\n                 'default'  => '',\n+                'disabled' => $custom_attribute_disabled,\n+                'row_data' => $custom_attribute_row_data,\n             );\n \n             $fields[] = array( \n                 'id'       => 'custom_attribute_value',\n                 'title'    => __( 'Custom Attribute Value', 'foogallery' ),\n-                'desc'     => __( 'Used in combination with \"Custom Attribute Key\" to add a custom attribute to the gallery container. To be used by developers only!', 'foogallery' ),\n+                'desc'     => __( 'Used in combination with \"Custom Attribute Key\" to add a custom attribute to the gallery container. Only administrators can edit this setting. To be used by developers only!', 'foogallery' ),\n                 'section'  => __( 'Advanced', 'foogallery' ),\n                 'type'     => 'text',\n                 'default'  => '',\n+                'disabled' => $custom_attribute_disabled,\n+                'row_data' => $custom_attribute_row_data,\n             );\n \n \t\t\t$fields[] = array(\n@@ -145,18 +247,11 @@\n \t\t\tglobal $current_foogallery;\n \n \t\t\tif ( $current_foogallery === $gallery ) {\n-                $custom_attribute_key = sanitize_title( foogallery_gallery_template_setting( 'custom_attribute_key', '' ) );\n-                $custom_attribute_value = sanitize_text_field( foogallery_gallery_template_setting( 'custom_attribute_value', '' ) );\n+                $custom_attribute_key = foogallery_sanitize_custom_attribute_key( $this->get_saved_custom_attribute_setting( $gallery, 'custom_attribute_key' ), $gallery );\n+                $custom_attribute_value = foogallery_sanitize_custom_attribute_value( $this->get_saved_custom_attribute_setting( $gallery, 'custom_attribute_value' ) );\n \n                 if ( !empty( $custom_attribute_key ) && !empty( $custom_attribute_value ) ) {\n-\n-                    \u002F\u002Fdo further cleaning!\n-                    $custom_attribute_key = foogallery_sanitize_javascript( $custom_attribute_key );\n-                    $custom_attribute_value = foogallery_sanitize_javascript( $custom_attribute_value );\n-\n-                    if ( !empty( $custom_attribute_key ) && !empty( $custom_attribute_value ) ) {\n-                        $attributes[$custom_attribute_key] = $custom_attribute_value;\n-                    }\n+                    $attributes[$custom_attribute_key] = $custom_attribute_value;\n                 }\n             }","To exploit this vulnerability, an attacker with at least Contributor-level privileges can follow these steps:\n\n1.  **Create or Edit a Gallery:** Access the FooGallery menu in the WordPress dashboard and create a new gallery or edit an existing one.\n2.  **Configure Malicious Attributes:** Navigate to the 'Advanced' section of the gallery settings. Set the `custom_attribute_key` to a JavaScript event handler that is not included in the plugin's restricted blacklist (e.g., `onmouseenter` or `onfocus`). \n3.  **Define the Payload:** Set the `custom_attribute_value` to the desired JavaScript execution string (e.g., `alert(document.domain)`).\n4.  **Publish and Trigger:** Insert the gallery shortcode into a post or page. When a user (including an administrator) visits the page and triggers the specified event (e.g., by hovering their mouse over the gallery container), the injected script will execute in the context of their session.","gemini-3-flash-preview","2026-06-26 00:32:19","2026-06-26 00:33:58",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","3.1.31","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ffoogallery\u002Ftags\u002F3.1.31","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Ffoogallery.3.1.31.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ffoogallery\u002Ftags\u002F3.1.32","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Ffoogallery.3.1.32.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Ffoogallery\u002Ftags"]