ReviewX – WooCommerce Product Reviews with Multi-Criteria, Reminder Emails, Google Reviews, Schema & More <= 2.2.10 - Incorrect Authorization to Unauthenticated Information Exposure and Data Manipulation
Description
The ReviewX – WooCommerce Product Reviews with Multi-Criteria, Reminder Emails, Google Reviews, Schema & More plugin for WordPress is vulnerable to unauthorized access of data due to improper authorization checks on the userAccessibility() function in all versions up to, and including, 2.2.10. This makes it possible for unauthenticated attackers to access protected REST API endpoints, extract and modify information related to users and plugin's configuration
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v2.2.12
Source Code
WordPress.org SVN# Research Plan: CVE-2025-10736 ReviewX Improper Authorization ## 1. Vulnerability Summary The **ReviewX** plugin (versions <= 2.2.10) contains an improper authorization vulnerability in its REST API implementation. The core of the issue lies in the `userAccessibility()` function, which serves as a…
Show full research plan
Research Plan: CVE-2025-10736 ReviewX Improper Authorization
1. Vulnerability Summary
The ReviewX plugin (versions <= 2.2.10) contains an improper authorization vulnerability in its REST API implementation. The core of the issue lies in the userAccessibility() function, which serves as a permission_callback for various REST API routes. This function fails to correctly validate the authentication status or capabilities of the requester, allowing unauthenticated users to access endpoints intended for administrators. This leads to the exposure of sensitive user data and the ability to manipulate plugin configurations.
2. Attack Vector Analysis
- Endpoint Namespace:
reviewx/v1(inferred from plugin slug andWpApi.phplogic). - Base Route:
/wp-json/reviewx/v1/admin(based onBaseApi::getPrefix()returning/admin/api/v1). - Target Endpoints:
GET /wp-json/reviewx/v1/admin/get-settings: Information Exposure (Plugin Config).GET /wp-json/reviewx/v1/admin/get-users: Information Exposure (User Data).POST /wp-json/reviewx/v1/admin/update-settings: Data Manipulation (Plugin Config).
- Authentication: None required (Unauthenticated).
- Preconditions: The plugin must be active. No specific settings are required as the vulnerability exists in the core API registration.
3. Code Flow
- Request Entry: An unauthenticated HTTP request is made to a REST route registered by the plugin (e.g.,
/wp-json/reviewx/v1/admin/get-settings). - Route Matching: WordPress matches the request to the ReviewX REST controller.
- Permission Check: WordPress calls the
permission_callbackassociated with the route. Based on the vulnerability description, this is theuserAccessibility()function. - Vulnerable Logic: The
userAccessibility()function (likely located inapp/Rest/RestRoute.phpor similar, though file not provided) returnstrueor fails to perform acurrent_user_can('manage_options')check for unauthenticated users. - Execution: Because the permission check passes, the controller method (e.g.,
get_settings) executes and returns sensitive data or processes a configuration update.
4. Nonce Acquisition Strategy
While the vulnerability description suggests improper authorization (meaning the permission_callback itself is flawed), WordPress REST API generally requires a X-WP-Nonce for authenticated stateful requests (via cookies). For unauthenticated requests, the permission_callback is the primary gatekeeper.
If the userAccessibility() function explicitly checks for a nonce or if we need to simulate a "legitimate" request context:
- Identify Script Loading: ReviewX enqueues scripts on pages containing its shortcodes.
- Create Trigger Page: Create a page with the
[reviewx_pagination]shortcode.wp post create --post_type=page --post_status=publish --post_content='[reviewx_pagination]'
- Navigate and Extract: Use the browser to load the page and extract the localized data.
- JS Variable: ReviewX typically uses
rvx_params. - Extraction Command:
browser_eval("window.rvx_params?.nonce")orbrowser_eval("window.rvx_params?.rest_nonce")
Note: If userAccessibility() returns true unconditionally, no nonce is required for the exploit.
5. Exploitation Strategy
Phase 1: Information Exposure (Plugin Settings)
- Target: Retrieve plugin configuration.
- Request:
GET /wp-json/reviewx/v1/admin/get-settings HTTP/1.1 Host: TARGET_HOST - Tool:
http_request
Phase 2: Information Exposure (User Data)
- Target: Retrieve list of users.
- Request:
GET /wp-json/reviewx/v1/admin/get-users HTTP/1.1 Host: TARGET_HOST - Tool:
http_request
Phase 3: Data Manipulation (Configuration Update)
- Target: Disable a feature or change a setting (e.g., setting
enable_photo_reviewtofalse). - Request:
POST /wp-json/reviewx/v1/admin/update-settings HTTP/1.1 Host: TARGET_HOST Content-Type: application/json { "settings": { "enable_photo_review": false } } - Tool:
http_request
6. Test Data Setup
- Install Plugin: Ensure ReviewX <= 2.2.10 is installed and active.
- Create Dummy Users: Create a few users with different roles to verify they appear in the
get-usersoutput.wp user create victim1 victim1@example.com --role=editor
- Configure Settings: Set some initial values in the ReviewX admin panel (if accessible) or via CLI to have something to change.
- Create Page for Nonce (Backup):
wp post create --post_type=page --post_title="Review Test" --post_status=publish --post_content='[reviewx_pagination]' --post_name='review-test'
7. Expected Results
- Information Exposure: The
get-settingsrequest should return a JSON object containing plugin configuration keys (e.g.,license_key,email_settings, etc.). Theget-usersrequest should return a list of WordPress users. - Data Manipulation: The
update-settingsrequest should return a success message (e.g.,{"success": true}).
8. Verification Steps
- Check Exposed Data: Inspect the JSON response from Phase 1 and 2 for sensitive fields.
- Verify Configuration Change: Use WP-CLI to check the option value in the database after Phase 3.
wp option get reviewx_settings(Note: the option name might bervx_settingsor similar; checkwp option list --search="*reviewx*"first).
- Compare State: Verify the change in the WordPress admin dashboard under ReviewX Settings.
9. Alternative Approaches
- Alternative Namespaces: If
reviewx/v1fails, tryrvx/v1orreviewx/api/v1(based onWpApi.phpbase URL logic). - Alternative Methods: Some plugins use
_method=POSTor_method=PUTparameters if the server blocks certain verbs. - Parameter Fuzzing: If
update-settingsrequires a specific structure, use the output ofget-settingsas a template for thePOSTpayload. - Direct Option Access: Check for routes like
GET /wp-json/reviewx/v1/admin/optionsif the above endpoints are 404.
Summary
The ReviewX plugin fails to implement proper authorization checks within the `userAccessibility()` function, which acts as a permission callback for various REST API routes. This oversight allows unauthenticated attackers to access administrative endpoints to retrieve sensitive user data and modify the plugin's internal configuration.
Security Fix
@@ -35,6 +35,6 @@ */ public function getDefaultHeaders() : array { - return ['Authorization' => '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 ['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']; } } @@ -72,6 +72,7 @@ $headers = ['Content-Type' => 'application/json']; if ($this->token) { $headers['Authorization'] = 'Bearer ' . $this->token; + $headers['X-Auth-Token'] = 'Bearer ' . $this->token; } return $headers; }
Exploit Outline
The exploit involves sending unauthenticated requests to the plugin's REST API endpoints located under the `/wp-json/reviewx/v1/admin/` namespace. Because the `userAccessibility()` permission callback incorrectly returns true for unauthenticated users, an attacker can access sensitive information or perform unauthorized actions. To extract data, an attacker sends a GET request to `/wp-json/reviewx/v1/admin/get-settings` (plugin configuration) or `/wp-json/reviewx/v1/admin/get-users` (user database). To manipulate data, an attacker sends a POST request to `/wp-json/reviewx/v1/admin/update-settings` with a JSON payload containing modified settings. No nonce or valid session cookie is required to bypass the flawed authorization check.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.