Customer Reviews for WooCommerce <= 5.101.0 - Reflected Cross-Site Scripting via 'crsearch'
Description
The Customer Reviews for WooCommerce plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the ‘crsearch’ parameter in all versions up to, and including, 5.101.0 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a link.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:NTechnical Details
<=5.101.0What Changed in the Fix
Changes introduced in v5.102.0
Source Code
WordPress.org SVNThis exploitation research plan targets a reflected Cross-Site Scripting (XSS) vulnerability in the **Customer Reviews for WooCommerce** plugin (<= 5.101.0). The vulnerability arises because the plugin reflects the `crsearch` GET parameter into the HTML search interface without proper escaping. ###…
Show full research plan
This exploitation research plan targets a reflected Cross-Site Scripting (XSS) vulnerability in the Customer Reviews for WooCommerce plugin (<= 5.101.0). The vulnerability arises because the plugin reflects the crsearch GET parameter into the HTML search interface without proper escaping.
1. Vulnerability Summary
- Vulnerability: Reflected Cross-Site Scripting (XSS).
- Vulnerable Parameter:
crsearch(GET). - Vulnerable Component: The "All Reviews" shortcode/block UI.
- Sink: An HTML
<input>element'svalueattribute or a text node within the search UI. - Cause: The plugin retrieves the search query from
$_GET['crsearch']and echoes it back to the user in the search field's value attribute without usingesc_attr()oresc_html().
2. Attack Vector Analysis
- Endpoint: Any public-facing WordPress page or post containing the
[cusrev_all_reviews]shortcode. - Payload Parameter:
crsearch. - Authentication: None required (Unauthenticated).
- Preconditions: A page must exist with the
[cusrev_all_reviews]shortcode rendered.
3. Code Flow
- Entry Point: A user visits a URL with the parameter
?crsearch=<payload>. - Shortcode Handling: WordPress processes the
[cusrev_all_reviews]shortcode viaCR_All_Reviews::render_all_reviews_shortcode()(defined inincludes/blocks/class-cr-all-reviews.php). - UI Generation: This method calls
display_reviews(). - Hook Trigger: Inside
display_reviews(), the plugin triggers the action hookdo_action( 'cr_reviews_search' ). - Vulnerable Sink: The class
CR_Ajax_Reviews(inincludes/reviews/class-cr-ajax-reviews.php) registers a handler for this hook:add_action( 'cr_reviews_search', array( 'CR_Ajax_Reviews', 'display_search_ui' ) ); - Reflection: The
display_search_ui()function (inferred logic based on plugin behavior) retrieves$_GET['crsearch']and echoes it directly into thevalueattribute of a search<input>field:// Predicted vulnerable code in display_search_ui() $search_query = isset( $_GET['crsearch'] ) ? $_GET['crsearch'] : ''; echo '<input type="text" class="cr-search-input" value="' . $search_query . '">';
4. Nonce Acquisition Strategy
This is a Reflected XSS vulnerability in a standard GET request that renders HTML.
- Nonce Requirement: No nonce is required for the reflection to occur, as it happens during the initial page load when the shortcode is processed.
- Bypass: The vulnerability exists in the output rendering of the page itself, not an AJAX endpoint that validates nonces before execution.
5. Exploitation Strategy
- Target URL Identification: Identify or create a page containing the
[cusrev_all_reviews]shortcode. - Payload Construction: Use a payload designed to break out of an HTML attribute and execute JavaScript:
- Payload:
"><script>alert(document.domain)</script> - URL Encoded:
%22%3E%3Cscript%3Ealert%28document.domain%29%3C%2Fscript%3E
- Payload:
- Request Execution: Use the
http_requesttool to perform a GET request to the target page with the payload.
6. Test Data Setup
- Plugin Activation: Ensure
customer-reviews-woocommerceversion 5.101.0 andwoocommerceare installed and active. - Page Creation: Create a public page containing the necessary shortcode:
wp post create --post_type=page --post_title="Reviews Test" --post_status=publish --post_content='[cusrev_all_reviews]' - Verify URL: Note the URL of the newly created page (e.g.,
/reviews-test/).
7. Expected Results
- The HTTP response will contain the literal, unescaped string:
value=""><script>alert(document.domain)</script>". - If viewed in a browser, the JavaScript
alert(document.domain)will execute.
8. Verification Steps
- Automated Check: Use the
http_requesttool to fetch the page with the payload and grep for the raw payload in the response body.response = http_request("GET", "http://wp.local/reviews-test/?crsearch=\"><script>alert(1)</script>") if '"><script>alert(1)</script>' in response['body']: print("Vulnerability Confirmed: Payload reflected unescaped.") - Manual Browser Check: Use
browser_navigateto the URL and check if the script executes or if the input field's value contains the payload.
9. Alternative Approaches
If the display_search_ui hook behaves differently, the reflection may occur in other parts of the "All Reviews" block:
- Alternative Sink: Check the "Search" button label or the "Results for..." text if the search has been "submitted".
- Payload Variation: If the input is inside a JSON object localized for JavaScript (via
wp_localize_script), use a payload to break out of a JS string:- Payload:
";alert(1);//
- Payload:
- AJAX Reflected XSS: If the search results are loaded via AJAX (action
cr_filter_reviews), the reflection might occur in the AJAX response. This would require obtaining the nonce from the localized script variable (e.g.,window.ivole_all_reviews_params.nonceor similar).
Summary
The Customer Reviews for WooCommerce plugin is vulnerable to Reflected Cross-Site Scripting (XSS) due to insufficient output escaping on the 'crsearch' parameter. This parameter is reflected into the value attribute of a search input field generated by the [cusrev_all_reviews] shortcode, allowing unauthenticated attackers to execute arbitrary scripts in a victim's browser.
Vulnerable Code
// includes/reviews/class-cr-ajax-reviews.php:749 public static function get_search_field( $search_button ) { $search_val = ''; $clear_class = 'cr-clear-input'; if( get_query_var( 'crsearch' ) ) { $search_val = strval( get_query_var( 'crsearch' ) ); if( 0 < mb_strlen( $search_val ) ) { $clear_class = 'cr-clear-input cr-visible'; } } --- // includes/reviews/class-cr-ajax-reviews.php:769 <input name="cr_input_text_search" class="cr-input-text" type="text" placeholder="'. esc_attr__( 'Search customer reviews', 'customer-reviews-woocommerce' ) .'" value="' . $search_val . '" aria-label="' . esc_attr__( 'Search customer reviews', 'customer-reviews-woocommerce' ) . '">
Security Fix
@@ -749,9 +749,9 @@ public static function get_search_field( $search_button ) { $search_val = ''; $clear_class = 'cr-clear-input'; - if( get_query_var( 'crsearch' ) ) { + if ( get_query_var( 'crsearch' ) ) { $search_val = strval( get_query_var( 'crsearch' ) ); - if( 0 < mb_strlen( $search_val ) ) { + if ( 0 < strlen( $search_val ) ) { $clear_class = 'cr-clear-input cr-visible'; } } @@ -766,7 +766,7 @@ <path fill-rule="evenodd" d="M10.442 10.442a1 1 0 0 1 1.415 0l3.85 3.85a1 1 0 0 1-1.414 1.415l-3.85-3.85a1 1 0 0 1 0-1.415z"/> <path fill-rule="evenodd" d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zM13 6.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/> </svg> - <input name="cr_input_text_search" class="cr-input-text" type="text" placeholder="'. esc_attr__( 'Search customer reviews', 'customer-reviews-woocommerce' ) .'" value="' . $search_val . '" aria-label="' . esc_attr__( 'Search customer reviews', 'customer-reviews-woocommerce' ) . '"> + <input name="cr_input_text_search" class="cr-input-text" type="text" placeholder="'. esc_attr__( 'Search customer reviews', 'customer-reviews-woocommerce' ) .'" value="' . esc_attr( $search_val ) . '" aria-label="' . esc_attr__( 'Search customer reviews', 'customer-reviews-woocommerce' ) . '">
Exploit Outline
1. Identify a public page or post on the target WordPress site that contains the [cusrev_all_reviews] shortcode. 2. Construct a malicious URL by appending the 'crsearch' GET parameter with a payload designed to break out of an HTML attribute and execute JavaScript (e.g., ?crsearch="><script>alert(document.domain)</script>). 3. Entice an unauthenticated user or administrator to click the link. 4. When the page renders, the CR_Ajax_Reviews::get_search_field() method retrieves the 'crsearch' value and echoes it directly into the 'value' attribute of the search input field without escaping, resulting in script execution.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.