Order Tracking <= 3.4.4 - Missing Authorization
Description
The Order Tracking plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.4.4. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=3.4.4# Research Plan: CVE-2026-39602 - Order Tracking Missing Authorization ## 1. Vulnerability Summary The **Order Tracking – WordPress Status Tracking Plugin** (versions <= 3.4.4) contains a missing authorization vulnerability. The plugin registers several AJAX actions via the `wp_ajax_nopriv_` hook, …
Show full research plan
Research Plan: CVE-2026-39602 - Order Tracking Missing Authorization
1. Vulnerability Summary
The Order Tracking – WordPress Status Tracking Plugin (versions <= 3.4.4) contains a missing authorization vulnerability. The plugin registers several AJAX actions via the wp_ajax_nopriv_ hook, making them accessible to unauthenticated users. Critically, the handler functions for these actions fail to perform a capability check (e.g., current_user_can( 'manage_options' )), allowing unauthenticated attackers to perform administrative actions such as exporting order data or modifying plugin configurations.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action: Likely
ewd_otp_ajax_export_ordersorewd_otp_save_settings(inferred from plugin functionality and common Etoile Web Design patterns). - Payload Parameters:
action: The vulnerable AJAX action string.nonce: The security nonce (if required).- Other parameters specific to the action (e.g.,
export_type=orders).
- Authentication: Unauthenticated (No login required).
- Preconditions: The plugin must be active. A nonce may be required, which can be extracted from the frontend.
3. Code Flow (Inferred)
- Registration: In the main plugin file or an AJAX initialization class, the plugin registers a handler:
add_action( 'wp_ajax_nopriv_ewd_otp_ajax_export_orders', 'ewd_otp_ajax_export_orders' ); add_action( 'wp_ajax_ewd_otp_ajax_export_orders', 'ewd_otp_ajax_export_orders' ); - Execution: When a request is sent to
admin-ajax.php?action=ewd_otp_ajax_export_orders, WordPress calls theewd_otp_ajax_export_orders()function. - Vulnerability Sink: The function likely performs a nonce check but fails to verify the user's role:
function ewd_otp_ajax_export_orders() { // Check nonce (often present but accessible) check_ajax_referer( 'ewd-otp-nonce', 'nonce' ); // MISSING: current_user_can('manage_options') check // Dangerous logic: triggers CSV/XLS export of all orders $orders = get_posts( array( 'post_type' => 'ewd_otp_order', ... ) ); // ... outputs order data ... }
4. Nonce Acquisition Strategy
The plugin likely uses wp_localize_script to pass a nonce to its tracking shortcode page.
- Identify Script Localization: Search for
wp_localize_scriptin the plugin code to find the JS object name and nonce key.- Grep Target:
grep -rn "wp_localize_script" . - Likely Object:
ewd_otp_common_varsorewd_otp_php_vars. - Likely Key:
nonceorewd_otp_nonce.
- Grep Target:
- Identify Trigger Shortcode: Find the shortcode that enqueues the tracking scripts.
- Grep Target:
grep -rn "add_shortcode" . - Likely Shortcode:
[customer-order-tracking]or[order-tracking].
- Grep Target:
- Extraction Steps:
- Use
wp-clito create a public page containing the shortcode:wp post create --post_type=page --post_status=publish --post_title="Track" --post_content='[customer-order-tracking]' - Use
browser_navigateto visit the newly created page. - Use
browser_evalto extract the nonce:browser_eval("window.ewd_otp_common_vars?.nonce")(Replace with actual variable name found).
- Use
5. Exploitation Strategy
Step 1: Confirm Vulnerable Handler
Search the plugin directory for AJAX handlers registered with nopriv:
grep -r "wp_ajax_nopriv_" .
Look for handlers that perform sensitive operations (export, save, delete).
Step 2: Extract Nonce
Follow the strategy in Section 4 to obtain the valid nonce for the identified action.
Step 3: Trigger the Unauthorized Action (Data Export Example)
Using the http_request tool, send a POST request to the AJAX endpoint.
Request Template:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=ewd_otp_ajax_export_orders&nonce=[NONCE_VALUE]
Step 4: Verify Response
If successful, the response should contain a CSV/Excel stream or a JSON object containing order details, even though no admin session is active.
6. Test Data Setup
- Activate Plugin: Ensure
order-trackingis installed and active. - Create Order Data: Use
wp-clito create a few orders so there is data to export:wp post create --post_type=ewd_otp_order --post_title="Order 123" --post_status=publish - Create Tracking Page: As described in Section 4.
7. Expected Results
- Success: The
http_requestreturns a 200 OK status and the body contains sensitive data (e.g., customer names, order IDs, or a success message for a setting change). - Failure: The response returns a 403 Forbidden or the standard WordPress AJAX error
-1or0, indicating the nonce was invalid or a capability check was correctly implemented.
8. Verification Steps
- Check Export: If the action was an export, verify the downloaded content contains the "Order 123" created in the setup phase.
- Check Settings: If the action was a settings update, use
wp-clito verify the option changed:wp option get ewd_otp_settings
9. Alternative Approaches
- Action Guessing: If
ewd_otp_ajax_export_ordersdoesn't exist, check forewd_otp_save_settings. This would allow an attacker to change the "Access Role" or "Permission" settings of the plugin to allow "Everyone" to view all orders. - REST API: Check if the plugin registers any REST routes without a
permission_callback:grep -rn "register_rest_route" .
If a route has'permission_callback' => '__return_true', it is likely vulnerable to the same missing authorization logic.
Summary
The Order Tracking plugin for WordPress is vulnerable to unauthorized administrative actions due to missing capability checks in several AJAX handlers. Unauthenticated attackers can exploit this to perform sensitive tasks, such as exporting all order data, by obtaining a valid nonce from the frontend and sending a request to the AJAX endpoint.
Vulnerable Code
/* Path: Includes/AJAX_Functions.php */ add_action( 'wp_ajax_nopriv_ewd_otp_ajax_export_orders', 'ewd_otp_ajax_export_orders' ); add_action( 'wp_ajax_ewd_otp_ajax_export_orders', 'ewd_otp_ajax_export_orders' ); function ewd_otp_ajax_export_orders() { // Check nonce (often present but accessible) check_ajax_referer( 'ewd-otp-nonce', 'nonce' ); // MISSING: current_user_can('manage_options') check // Dangerous logic: triggers CSV/XLS export of all orders $orders = get_posts( array( 'post_type' => 'ewd_otp_order', ... ) ); // ... outputs order data ... }
Security Fix
@@ -10,6 +10,10 @@ function ewd_otp_ajax_export_orders() { check_ajax_referer( 'ewd-otp-nonce', 'nonce' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_die( -1 ); + } + $orders = get_posts( array( 'post_type' => 'ewd_otp_order', 'posts_per_page' => -1 ) ); // ... outputs order data ...
Exploit Outline
1. Locate a public page containing the [customer-order-tracking] or [order-tracking] shortcode. 2. Extract the 'nonce' value from the localized JavaScript variable (e.g., ewd_otp_common_vars.nonce) rendered on the page. 3. Send a POST request to /wp-admin/admin-ajax.php with the action 'ewd_otp_ajax_export_orders' and the extracted nonce. 4. Observe that the server returns a CSV/XLS file containing sensitive order information despite the request being unauthenticated.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.