Smart Online Order for Clover <= 1.6.0 - Unauthenticated Sensitive Information Exposure
Description
The Smart Online Order for Clover plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 1.6.0. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=1.6.0What Changed in the Fix
Changes introduced in v1.6.1
Source Code
WordPress.org SVN## Vulnerability Summary The **Smart Online Order for Clover** plugin (versions <= 1.6.0) is vulnerable to **Unauthenticated Sensitive Information Exposure**. The vulnerability exists in the plugin's REST API implementation within the `moo-clover/v1` namespace. Specifically, several REST API route…
Show full research plan
Vulnerability Summary
The Smart Online Order for Clover plugin (versions <= 1.6.0) is vulnerable to Unauthenticated Sensitive Information Exposure. The vulnerability exists in the plugin's REST API implementation within the moo-clover/v1 namespace.
Specifically, several REST API routes registered in includes/moo-OnlineOrders-Restapi.php (and its associated sub-route classes like CustomersRoutes and DashboardRoutes) use 'permission_callback' => '__return_true', allowing unauthenticated access to endpoints that return merchant statistics, order history, and customer details. This data is retrieved via the Moo_OnlineOrders_SooApi class and exposed to any requester without identity verification.
Attack Vector Analysis
- Endpoint: WordPress REST API
- Namespace:
moo-clover/v1 - Vulnerable Routes:
/wp-json/moo-clover/v1/customers(Inferred fromCustomersRoutes)/wp-json/moo-clover/v1/dashboard/stats(Inferred fromDashboardRoutes)/wp-json/moo-clover/v1/dashboard/orders(Inferred fromDashboardRoutes)
- Method:
GET - Authentication: None (Unauthenticated)
- Preconditions: The plugin must be activated. For a successful data leak, the plugin must be connected to a Clover merchant account, or have cached/local data available.
Code Flow
- Registration: During
rest_api_init,Moo_OnlineOrders_Restapi::register_routes()is called. - Sub-Route Initialization: The constructor in
includes/moo-OnlineOrders-Restapi.phpinstantiatesCustomersRoutesandDashboardRoutes. - Endpoint Definition: Inside
DashboardRoutes->register_routes()(and others), routes are registered usingregister_rest_route. - Missing Authorization: The routes are configured with
'permission_callback' => '__return_true'. - Data Retrieval: When an attacker hits
/wp-json/moo-clover/v1/customers, the callback invokes methods inMoo_OnlineOrders_SooApi. - Exposure: The API response (containing names, emails, order totals, or merchant financial stats) is returned directly to the unauthenticated user in JSON format.
Nonce Acquisition Strategy
Based on the code in includes/moo-OnlineOrders-Restapi.php, these endpoints are intended for public or dashboard use and do not implement manual nonce checks within the callback functions.
The WordPress REST API does not require a nonce for unauthenticated GET requests where the permission_callback is __return_true. Nonces are only required when using Cookie-based authentication for sensitive state-changing operations.
Therefore, no nonce is required to exploit this information exposure.
Exploitation Strategy
The goal is to demonstrate that sensitive merchant/customer data can be retrieved without a session.
Step 1: Discover Endpoints
Send unauthenticated requests to the suspected sensitive endpoints.
Request:
GET /wp-json/moo-clover/v1/dashboard/stats HTTP/1.1
Host: TARGET_HOST
Step 2: Extract Customer Data
Request:
GET /wp-json/moo-clover/v1/customers HTTP/1.1
Host: TARGET_HOST
Step 3: Extract Order History
Request:
GET /wp-json/moo-clover/v1/dashboard/orders HTTP/1.1
Host: TARGET_HOST
Test Data Setup
To verify the leak in a test environment:
- Install and activate the plugin (v1.6.0).
- The plugin typically requires a Clover API Key to function. In a mock environment, you may need to simulate a successful connection or check if the plugin exposes "empty" structures that still prove the endpoint's lack of protection.
- Alternatively, if the plugin uses local DB tables (like
wp_moo_itemfound inProducts_List_Moo), ensure there is data in the database:wp db query "INSERT INTO wp_moo_item (uuid, name, soo_name, price) VALUES ('test-uuid', 'Secret Item', 'Secret Item', 1000);"
Expected Results
- Success: The server returns a
200 OKstatus code with a JSON body. - Content: The JSON contains merchant statistics (e.g., total sales, order counts) or customer PII (names, emails) instead of a
401 Unauthorizedor403 Forbiddenerror. - Structure:
{ "stats": { "total_orders": 150, "total_revenue": 5000.00 }, "customers": [ { "firstName": "John", "lastName": "Doe", "email": "john@example.com" } ] }
Verification Steps
- Check Status: Confirm the HTTP response code is
200. - Verify Authentication Absence: Ensure the request was sent without any
Authorizationheaders orwordpress_logged_incookies. - Confirm Permissions: Use WP-CLI to check if the routes are registered:
wp rest route list --namespace=moo-clover/v1 - Compare Output: Match the data returned by the REST API with the data visible in the Clover Orders admin dashboard (
wp-admin/admin.php?page=moo_orders).
Alternative Approaches
If /dashboard/stats is restricted in the specific test version, attempt to access the "Settings" exposure. Some versions of the plugin were reported to leak the Clover API key via:
/wp-json/moo-clover/v1/settings- Locating the
moo_paramsobject in the frontend source:- Create a page with the shortcode
[moo_all_items]. - Use
browser_navigateto the page. browser_eval("window.moo_params")to see if sensitive configuration keys are localized to the frontend.
- Create a page with the shortcode
Summary
The Smart Online Order for Clover plugin for WordPress is vulnerable to unauthenticated sensitive information exposure due to improper access control on its REST API endpoints. Attackers can access merchant financial statistics, customer PII, and order history via the 'moo-clover/v1' namespace because sensitive routes are registered with a public permission callback.
Vulnerable Code
// includes/moo-OnlineOrders-Restapi.php lines 126-127 $this->dashRoutes = new DashboardRoutes($this->model, $this->api); $this->customersRoutes = new CustomersRoutes($this->model, $this->api); --- // includes/moo-OnlineOrders-Restapi.php lines 149-150 $this->dashRoutes->register_routes(); $this->customersRoutes->register_routes(); --- // Pattern of unauthenticated access registration in includes/moo-OnlineOrders-Restapi.php:157 register_rest_route( $this->namespace, '/categories', array( array( 'methods' => 'GET', 'callback' => array( $this, 'getCategories' ), 'permission_callback' => '__return_true' ) ) );
Security Fix
@@ -15,7 +15,7 @@ array( 'methods' => 'GET', 'callback' => array( $this, 'get_customers' ), - 'permission_callback' => '__return_true' + 'permission_callback' => function () { return current_user_can( 'manage_options' ); } ) ) ); @@ -20,7 +20,7 @@ array( 'methods' => 'GET', 'callback' => array( $this, 'get_stats' ), - 'permission_callback' => '__return_true' + 'permission_callback' => function () { return current_user_can( 'manage_options' ); } ) ) );
Exploit Outline
An attacker sends unauthenticated GET requests to the WordPress REST API endpoints located under the '/wp-json/moo-clover/v1/' namespace. Specifically, targeting '/dashboard/stats' allows for the retrieval of merchant financial performance data, while the '/customers' endpoint returns a JSON list of customer names and contact information. No nonces, cookies, or authorization headers are required to exploit this vulnerability because the 'permission_callback' for these routes is explicitly set to '__return_true' in versions up to 1.6.0.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.