[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fwHI_sw1D7Gu7wqXj8sGurw7ZeMTUZsVUOKxK1wUrvgY":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":29,"research_verified":30,"research_rounds_completed":31,"research_plan":32,"research_summary":33,"research_vulnerable_code":34,"research_fix_diff":35,"research_exploit_outline":36,"research_model_used":37,"research_started_at":38,"research_completed_at":39,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":30,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":30,"source_links":40},"CVE-2026-2381","woocommerce-stripe-payment-gateway-missing-authorization-to-unauthenticated-order-status-manipulation-via-order-paramete","WooCommerce Stripe Payment Gateway \u003C= 10.7.0 - Missing Authorization to Unauthenticated Order Status Manipulation via 'order' Parameter","The WooCommerce Stripe Payment Gateway plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the `ajax_pay_for_order()` function in all versions up to, and including, 10.7.0 This is due to a missing order ownership or order_key verification when processing payment for an order via the `wc_stripe_pay_for_order` WC-AJAX endpoint. The function only validates a nonce (which is publicly available on any WooCommerce page where Express Checkout is enabled), but does not verify that the requesting user owns the target order and is allowed to modify it. This makes it possible for unauthenticated attackers to force any pending order into a failed status by providing a fake payment method, causing a payment exception that updates the order status to \"failed\" via sequential order ID enumeration.","woocommerce-gateway-stripe",null,"\u003C=10.7.0","10.8.0","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:L","Missing Authorization","2026-06-15 21:08:36","2026-06-16 09:31:35",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fab3b52f7-e2c3-44f7-8e19-b6c51ccd50e0?source=api-prod",1,[22,23,24,25,26,27,28],"assets\u002Fcss\u002Fstripe-styles.css","assets\u002Fcss\u002Fstripe-styles.css.map","assets\u002Fcss\u002Fstripe-styles.scss","assets\u002Fjs\u002Fstripe.js","assets\u002Fjs\u002Fstripe.min.js","build\u002Famazon-pay-settings.asset.php","build\u002Famazon-pay-settings.js","researched",false,3,"# Exploitation Research Plan: CVE-2026-2381\n\n## 1. Vulnerability Summary\nThe **WooCommerce Stripe Payment Gateway** plugin (\u003C= 10.7.0) contains a missing authorization vulnerability in its AJAX handler for order payments. Specifically, the function `ajax_pay_for_order()` (registered via the `wc_stripe_pay_for_order` WC-AJAX endpoint) fails to verify order ownership or validate the `order_key`. \n\nWhile the function checks a WordPress nonce, this nonce is exposed to unauthenticated users on any page where Stripe Express Checkout is enabled. Consequently, an unauthenticated attacker can supply an arbitrary Order ID and a malformed payment method. This triggers a payment exception within the plugin's logic, which the plugin handles by automatically updating the status of the targeted order to \"failed\".\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** `[TARGET_URL]\u002F?wc-ajax=wc_stripe_pay_for_order` (The `wc-ajax` query parameter triggers the WooCommerce AJAX handler).\n*   **Action Identifier:** `wc_stripe_pay_for_order`\n*   **Vulnerable Parameter:** `order` (Used to specify the target Order ID).\n*   **Authentication:** None required (Unauthenticated).\n*   **Preconditions:** \n    1.  The targeted order must be in a \"Pending Payment\" status.\n    2.  The \"Payment Request Buttons\" (Express Checkout) must be enabled in Stripe settings to expose the required nonce.\n\n## 3. Code Flow\n1.  **Entry Point:** The request hits `admin-ajax.php` or `index.php` with `?wc-ajax=wc_stripe_pay_for_order`.\n2.  **Hook Registration:** The plugin registers the AJAX handler (typically in a class like `WC_Stripe_Payment_Gateway_Ajax` or similar):\n    `add_action( 'wc_ajax_wc_stripe_pay_for_order', array( $this, 'ajax_pay_for_order' ) );`\n3.  **Handler Execution:** `ajax_pay_for_order()` is called.\n4.  **Nonce Verification:** The function calls `check_ajax_referer( 'wc_stripe_pay_for_order', '_wpnonce' )`.\n5.  **Missing Check (The Vulnerability):** The function retrieves the order using `wc_get_order( $_POST['order'] )`. Crucially, it **does not** verify that the current user is the owner of the order or that a valid `order_key` (secret token) was provided.\n6.  **Payment Processing:** The function attempts to process payment using the provided `payment_method`. \n7.  **Exception Handling:** If the `payment_method` is invalid (e.g., `pi_invalid`), the Stripe API client throws an exception.\n8.  **Sink:** The `catch` block in `ajax_pay_for_order()` catches the exception and calls `$order->update_status( 'failed', ... )`, effectively modifying the order data without authorization.\n\n## 4. Nonce Acquisition Strategy\nThe nonce for the `wc_stripe_pay_for_order` action is localized in the `wc_stripe_params` object when the Stripe scripts are enqueued. \n\n1.  **Identify Trigger:** The nonce is enqueued on product pages or the cart page when \"Payment Request Buttons\" are active.\n2.  **Navigation:** Use `browser_navigate` to visit a public product page.\n3.  **Extraction:** Execute JavaScript to retrieve the nonce from the global parameters object defined in `assets\u002Fjs\u002Fstripe.js`.\n    *   **JS Variable:** `wc_stripe_params`\n    *   **Action Key:** Based on the script localization logic, look for the nonce associated with the payment flow.\n    *   **Command:** `browser_eval(\"wc_stripe_params.nonce.pay_for_order\")` (Note: The exact key inside `wc_stripe_params` may be `_ajax_nonce` or nested under a `nonce` key; verify by inspecting the `wc_stripe_params` object).\n\n## 5. Exploitation Strategy\nThe goal is to force a pending order into a \"failed\" status.\n\n1.  **Target Identification:** Identify a target Order ID (e.g., via sequential enumeration starting from a known recent order).\n2.  **Request Construction:**\n    *   **Method:** POST\n    *   **URL:** `https:\u002F\u002F[TARGET]\u002Findex.php?wc-ajax=wc_stripe_pay_for_order`\n    *   **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n    *   **Body Parameters:**\n        *   `order`: `[TARGET_ORDER_ID]`\n        *   `payment_method`: `pi_12345_fake` (Any string that causes a Stripe API failure).\n        *   `_wpnonce`: `[EXTRACTED_NONCE]`\n3.  **Execution:** Send the request using `http_request`.\n4.  **Observation:** The server will likely return a JSON response containing an error message related to the failed payment, which confirms the `catch` block was reached.\n\n## 6. Test Data Setup\n1.  **Configure Plugin:**\n    *   Enable WooCommerce and Stripe Gateway.\n    *   Enable \"Payment Request Buttons\" in the Stripe settings (Checkout -> Stripe -> Settings).\n2.  **Create Content:**\n    *   Create a simple product.\n3.  **Create Target Order:**\n    *   As a guest user, add the product to the cart and proceed to checkout.\n    *   Place an order using a \"Manual\" or \"Cheque\" method first, or simply leave the Stripe payment session unfinished to keep the order in `pending` status.\n    *   Record the Order ID (e.g., `123`).\n\n## 7. Expected Results\n*   **Response:** The AJAX endpoint returns a JSON success or failure message (e.g., `{\"result\":\"failure\",\"messages\":\"...\"}`).\n*   **State Change:** The targeted order's status in the WooCommerce database changes from `pending` (Pending Payment) to `failed`.\n*   **Audit Trail:** An order note is added stating that the payment failed, often including the fake payment ID or error message.\n\n## 8. Verification Steps\n1.  **Check Status via CLI:**\n    `wp wc order get [ORDER_ID] --field=status --user=[ADMIN_USER]`\n    *   If the result is `failed`, the exploit was successful.\n2.  **Check Order Notes:**\n    `wp wc order_note list [ORDER_ID] --user=[ADMIN_USER]`\n    *   Look for notes indicating a payment failure triggered via AJAX.\n\n## 9. Alternative Approaches\n*   **Order Enumeration:** If the specific Order ID is unknown, the agent should attempt the request across a range of IDs (e.g., `[LATEST_ID] - 10` to `[LATEST_ID]`).\n*   **Different Nonce Sources:** If the product page does not yield the nonce, check the Cart or Checkout pages using `browser_navigate`.\n*   **Varying Payment Methods:** If `pi_fake` is rejected by client-side validation (though this is a server-side check), try other invalid Stripe tokens like `tok_chargeDeclined`.","The WooCommerce Stripe Payment Gateway plugin suffers from a missing authorization vulnerability in its `ajax_pay_for_order()` function. An unauthenticated attacker can manipulate the status of pending orders to 'failed' by providing an arbitrary order ID and a malformed payment method to the `wc_stripe_pay_for_order` AJAX endpoint.","\u002F\u002F includes\u002Fclass-wc-stripe-ajax.php (approximate line 130)\n\npublic function ajax_pay_for_order() {\n    check_ajax_referer( 'wc_stripe_pay_for_order', '_wpnonce' );\n\n    try {\n        $order_id = isset( $_POST['order'] ) ? absint( $_POST['order'] ) : 0;\n        $order    = wc_get_order( $order_id );\n\n        if ( ! $order ) {\n            throw new Exception( __( 'Invalid order.', 'woocommerce-gateway-stripe' ) );\n        }\n\n        \u002F\u002F ... processing payment method from $_POST['payment_method'] ...\n\n    } catch ( Exception $e ) {\n        \u002F\u002F Vulnerability: The status is updated based on an invalid order ID \u002F payment method without verifying ownership\n        $order->update_status( 'failed', sprintf( __( 'Stripe payment failed: %s', 'woocommerce-gateway-stripe' ), $e->getMessage() ) );\n        wp_send_json_error( array( 'message' => $e->getMessage() ) );\n    }\n}","--- includes\u002Fclass-wc-stripe-ajax.php\n+++ includes\u002Fclass-wc-stripe-ajax.php\n@@ -134,7 +134,9 @@\n \t\ttry {\n \t\t\t$order_id = isset( $_POST['order'] ) ? absint( $_POST['order'] ) : 0;\n \t\t\t$order    = wc_get_order( $order_id );\n+\t\t\t$order_key = isset( $_POST['order_key'] ) ? wc_clean( wp_unslash( $_POST['order_key'] ) ) : '';\n \n-\t\t\tif ( ! $order ) {\n+\t\t\tif ( ! $order || ! $order->key_is_valid( $order_key ) ) {\n \t\t\t\tthrow new Exception( __( 'Invalid order.', 'woocommerce-gateway-stripe' ) );\n \t\t\t}","To exploit this vulnerability, an attacker first obtains a valid AJAX nonce for the `wc_stripe_pay_for_order` action, which is exposed in the `wc_stripe_params` JavaScript object on any product or cart page where Stripe Express Checkout is enabled. The attacker then sends a POST request to the `\u002F?wc-ajax=wc_stripe_pay_for_order` endpoint. The payload must include the target `order` ID, the extracted `_wpnonce`, and an invalid or malformed `payment_method` string (e.g., 'pi_fake'). Because the server-side handler fails to verify if the requester owns the order or has a valid order key, it proceeds to process the payment. The invalid payment method triggers a Stripe API exception, and the plugin's error handler automatically updates the targeted order's status to 'failed', allowing for unauthenticated status manipulation via sequential order ID enumeration.","gemini-3-flash-preview","2026-06-25 23:37:29","2026-06-25 23:38:40",{"type":41,"vulnerable_version":42,"fixed_version":11,"vulnerable_browse":43,"vulnerable_zip":44,"fixed_browse":45,"fixed_zip":46,"all_tags":47},"plugin","10.7.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwoocommerce-gateway-stripe\u002Ftags\u002F10.7.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwoocommerce-gateway-stripe.10.7.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwoocommerce-gateway-stripe\u002Ftags\u002F10.8.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwoocommerce-gateway-stripe.10.8.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwoocommerce-gateway-stripe\u002Ftags"]