CVE-2026-22481

BD Courier Order Ratio Checker <= 2.0.1 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The BD Courier Order Ratio Checker plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.0.1. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=2.0.1
PublishedJanuary 6, 2026
Last updatedJanuary 14, 2026
Research Plan
Unverified

This research plan outlines the methodology for analyzing and exploiting **CVE-2026-22481**, a missing authorization vulnerability in the **BD Courier Order Ratio Checker** plugin for WordPress. ## 1. Vulnerability Summary The **BD Courier Order Ratio Checker** plugin (versions <= 2.0.1) fails to i…

Show full research plan

This research plan outlines the methodology for analyzing and exploiting CVE-2026-22481, a missing authorization vulnerability in the BD Courier Order Ratio Checker plugin for WordPress.

1. Vulnerability Summary

The BD Courier Order Ratio Checker plugin (versions <= 2.0.1) fails to implement proper authorization checks (capabilities checks) on its administrative functions. While the plugin may use nonces for CSRF protection, it does not verify if the user performing the action has the necessary permissions (e.g., manage_options). This allows an authenticated attacker with low-level privileges (Subscriber) to execute sensitive actions, such as modifying plugin settings or order ratio configurations.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: The vulnerable action is likely registered via add_action( 'wp_ajax_...' ). Based on the plugin's functionality, candidates include (inferred):
    • bd_courier_save_settings
    • save_ratio_checker_options
    • update_courier_ratio_config
  • HTTP Method: POST
  • Parameters: Likely includes setting keys and values, along with a security nonce.
  • Authentication: Authenticated (Subscriber level or higher).
  • Preconditions: The attacker must be logged into the WordPress site as a Subscriber.

3. Code Flow (Inferred)

  1. Registration: The plugin registers an AJAX handler in its main file or an admin-specific file:
    add_action( 'wp_ajax_bd_courier_save_settings', 'bd_courier_save_settings_callback' );
  2. Entry Point: An authenticated user sends a POST request to admin-ajax.php with action=bd_courier_save_settings.
  3. Vulnerable Function: The callback function (e.g., bd_courier_save_settings_callback) is invoked.
  4. Missing Check: The function likely calls check_ajax_referer() to verify a nonce but fails to call current_user_can( 'manage_options' ).
  5. Sink: The function proceeds to update the WordPress database using update_option() or $wpdb->update() based on user-supplied parameters.

4. Nonce Acquisition Strategy

If the endpoint requires a nonce, it is likely localized for use in the admin dashboard. Even Subscribers can often access admin-ajax.php and see localized scripts if the plugin enqueues them for all logged-in users.

  1. Identify Shortcode/Page: Check the plugin source for add_shortcode or admin menu registrations.
  2. Create Test Page:
    wp post create --post_type=page --post_status=publish --post_title="Nonce Grab" --post_content="[bd_courier_ratio_checker]" (inferred shortcode)
  3. Extract Nonce:
    Use browser_navigate to view the page (or the dashboard as a Subscriber).
    Execute: browser_eval("window.bd_courier_params?.nonce") (Verify the object name in the page source; look for wp_localize_script calls in the plugin code).

5. Exploitation Strategy

The goal is to modify a plugin setting that affects the "Order Ratio" logic or general plugin behavior.

  1. Login as Subscriber: Use the http_request tool to authenticate and obtain session cookies.
  2. Identify Parameters: Analyze the plugin's settings page (as an admin) to see the POST body structure when saving settings. Parameters might look like:
    action=bd_courier_save_settings&ratio_threshold=99&enable_checker=0&security=[NONCE]
  3. Craft Payload:
    • URL: http://[TARGET]/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: action=bd_courier_save_settings&[SETTING_KEY]=[MALICIOUS_VALUE]&security=[NONCE]
  4. Execute Request: Use http_request with the Subscriber's cookies.

6. Test Data Setup

  1. Install Plugin: Install BD Courier Order Ratio Checker version 2.0.1.
  2. Create Attacker User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
  3. Configure Initial State: Set a known "safe" ratio threshold via the admin panel.
    wp option update bd_courier_threshold 10 (inferred option name)

7. Expected Results

  • The server should return a success response (e.g., {"success": true} or 1).
  • The plugin's settings in the database should be updated despite the request originating from a Subscriber.

8. Verification Steps

  1. Database Check: Use WP-CLI to verify the option has changed:
    wp option get bd_courier_threshold
  2. Functionality Check: Trigger the order ratio check on the frontend (e.g., during a WooCommerce checkout simulation) and observe if the new malicious threshold is applied.

9. Alternative Approaches

  • Settings API Bypass: If the plugin uses register_setting without a proper sanitize_callback or if the options page itself is accessible to lower roles via a direct URL, try accessing options.php directly.
  • Different Hooks: Check for admin_init hooks that do not check for is_admin() or capabilities, as admin_init runs on admin-ajax.php requests regardless of the user's administrative status.
  • Inferred Action Search: If bd_courier_save_settings is incorrect, search the plugin for wp_ajax and identify any callback that performs an update_option or update_user_meta call.

Check if your site is affected.

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