CVE-2026-39689

eShipper Commerce <= 2.16.12 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
2.16.13
Patched in
78d
Time to patch

Description

The eShipper Commerce plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.16.12. 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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=2.16.12
PublishedFebruary 23, 2026
Last updatedMay 11, 2026
Affected plugineshipper-commerce
Research Plan
Unverified

This exploitation research plan targets a **Missing Authorization** vulnerability in the **eShipper Commerce** plugin (CVE-2026-39689). Since specific source files were not provided, this plan focuses on identifying the unauthenticated entry points commonly found in this plugin's architecture and pr…

Show full research plan

This exploitation research plan targets a Missing Authorization vulnerability in the eShipper Commerce plugin (CVE-2026-39689). Since specific source files were not provided, this plan focuses on identifying the unauthenticated entry points commonly found in this plugin's architecture and provides a methodology for the automated agent to locate and exploit them.


1. Vulnerability Summary

The eShipper Commerce plugin (<= 2.16.12) fails to implement proper capability checks (e.g., current_user_can()) on one or more of its AJAX or REST API handlers. This oversight allows unauthenticated users to trigger sensitive functions—likely related to shipping configurations, API key management, or order processing—by directly calling the exposed endpoints.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php or a WordPress REST API route (e.g., /wp-json/eshipper/v1/...).
  • Vulnerable Hooks: Look for actions registered with wp_ajax_nopriv_.
  • Potential Action Names (Inferred):
    • eshipper_save_settings
    • eshipper_update_api_credentials
    • eshipper_get_orders
    • eshipper_process_shipment
  • Authentication: None required (Unauthenticated).
  • Preconditions: The plugin must be active. Some endpoints might require a valid nonce, even if they lack authorization checks.

3. Code Flow (Trace Path)

  1. Initialization: The plugin initializes via the plugins_loaded or init hook.
  2. Registration: The plugin registers AJAX handlers using:
    add_action( 'wp_ajax_nopriv_<action>', array( $this, '<function_name>' ) );
  3. Handler Execution: When a request is sent to admin-ajax.php?action=<action>, WordPress invokes the registered <function_name>.
  4. The Vulnerability: Inside <function_name>, the code performs a sensitive operation (like update_option()) without first calling current_user_can( 'manage_options' ).
  5. Sink: User-controlled data from $_POST or $_REQUEST is passed to a WordPress database function or a setting update.

4. Nonce Acquisition Strategy

If the vulnerable handler calls check_ajax_referer() or wp_verify_nonce(), the agent must obtain a nonce. For unauthenticated (nopriv) handlers, nonces are tied to uid=0.

  1. Identify Script Localization: Search the codebase for wp_localize_script.
    • Grep command: grep -rn "wp_localize_script" wp-content/plugins/eshipper-commerce/
  2. Determine the Variable: Identify the JS object name (e.g., eshipper_vars) and the nonce key (e.g., nonce or ajax_nonce).
  3. Trigger Nonce Generation: Find which shortcode or admin page enqueues the script.
    • Grep command: grep -rn "add_shortcode" wp-content/plugins/eshipper-commerce/
  4. Extraction:
    • Create a test page: wp post create --post_type=page --post_status=publish --post_content='[target_shortcode]'
    • Use browser_navigate to visit that page.
    • Execute: browser_eval("window.eshipper_vars?.ajax_nonce") (Replace with actual variable name found).

5. Exploitation Strategy

The agent should prioritize finding an endpoint that allows modifying plugin settings.

  1. Identify Target: Search for wp_ajax_nopriv_ handlers that perform write operations.
    • grep -rn "wp_ajax_nopriv_" wp-content/plugins/eshipper-commerce/
  2. Construct Request: Assuming an action eshipper_update_settings is found:
    • Method: POST
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body:
      action=eshipper_update_settings&nonce=[NONCE]&eshipper_api_key=EXPLOITED_KEY&eshipper_origin_zip=90210
      
  3. Execute: Use the http_request tool to send the payload.

6. Test Data Setup

  1. Plugin Activation: Ensure the eShipper Commerce plugin is active.
  2. Configuration: (Optional) Set a baseline value for the target setting.
    • wp option update eshipper_api_key "LEGIT_KEY"
  3. Nonce Page: If a nonce is required, create the page containing the plugin's shortcode as described in Section 4.

7. Expected Results

  • Successful Response: The HTTP request returns a 200 OK (or 302 redirect) and likely a JSON response like {"success": true} or 1.
  • State Change: The targeted WordPress option (e.g., eshipper_api_key) is modified to the value provided in the exploit payload.

8. Verification Steps

After the HTTP request, verify the impact using WP-CLI:

  1. Check Settings: wp option get eshipper_api_key
  2. Check Database: If the exploit targeted custom tables:
    • wp db query "SELECT * FROM wp_eshipper_settings WHERE ..."
  3. Confirm Lack of Auth: Verify the same request fails if the nopriv hook is removed or if a capability check is added manually in the test environment (to confirm the vulnerability existed).

9. Alternative Approaches

  • REST API: If AJAX handlers are not vulnerable, check REST routes:
    • grep -rn "register_rest_route" wp-content/plugins/eshipper-commerce/
    • Look for routes where 'permission_callback' is either missing, set to __return_true, or lacks a current_user_can check.
  • Information Disclosure: If no write actions are found, look for unauthenticated nopriv handlers that call get_results on the database without authorization, allowing for data leakage.
  • Parameter Fuzzing: If the handler logic is complex, try including unexpected parameters like eshipper_debug_mode=1 or eshipper_enable_all_methods=1 to see if global plugin behavior can be altered.
Research Findings
Static analysis — not yet PoC-verified

Summary

The eShipper Commerce plugin for WordPress is vulnerable to unauthorized access in versions up to, and including, 2.16.12 due to a missing capability check on its AJAX or REST API handlers. This allows unauthenticated attackers to trigger sensitive functionality, such as modifying plugin settings or API credentials, by directly interacting with the exposed endpoints.

Exploit Outline

1. Identify target AJAX handlers by searching for 'wp_ajax_nopriv_' hooks in the plugin source that lack 'current_user_can()' calls. 2. Determine if a security nonce is required by checking for 'check_ajax_referer()' or 'wp_verify_nonce()'. 3. If a nonce is required, locate where the plugin localizes script data (e.g., 'wp_localize_script') and retrieve a nonce value from the site's front-end for a 'nopriv' session (UID 0). 4. Construct an unauthenticated POST request to '/wp-admin/admin-ajax.php' containing the vulnerable 'action' parameter and a malicious payload designed to overwrite plugin configuration (e.g., 'api_key=pwned'). 5. Submit the request and verify the state change using WP-CLI or by observing altered plugin behavior.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.