Piraeus Bank WooCommerce Payment Gateway <= 3.1.4 - Missing Authorization to Unauthenticated Arbitrary Order Status Change
Description
The Piraeus Bank WooCommerce Payment Gateway plugin for WordPress is vulnerable to unauthorized order status modification in all versions up to, and including, 3.1.4. This is due to missing authorization checks on the payment callback endpoint handler when processing the 'fail' callback from the payment gateway. This makes it possible for unauthenticated attackers to change any order's status to 'failed' via the publicly accessible WooCommerce API endpoint by providing only the order ID (MerchantReference parameter), which can be easily enumerated as order IDs are sequential integers. This can cause significant business disruption including canceled shipments, inventory issues, and loss of revenue.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=3.1.4Source Code
WordPress.org SVNPatched version not available.
This research plan focuses on CVE-2025-14460, a missing authorization vulnerability in the Piraeus Bank WooCommerce Payment Gateway plugin. The vulnerability allows unauthenticated users to change the status of any WooCommerce order to "failed" by interacting with the payment gateway's callback hand…
Show full research plan
This research plan focuses on CVE-2025-14460, a missing authorization vulnerability in the Piraeus Bank WooCommerce Payment Gateway plugin. The vulnerability allows unauthenticated users to change the status of any WooCommerce order to "failed" by interacting with the payment gateway's callback handler.
1. Vulnerability Summary
The Piraeus Bank WooCommerce Payment Gateway plugin (<= 3.1.4) implements a callback handler to process transaction results from the bank. When the bank reports a failed transaction, the plugin updates the corresponding WooCommerce order status. However, the code path handling the "fail" callback lacks sufficient authorization or authenticity checks (such as verifying a digital signature or a unique transaction token). Consequently, an attacker can manually trigger this "fail" logic for any order ID by sending a crafted request to the publicly accessible WooCommerce API endpoint.
2. Attack Vector Analysis
- Endpoint: The standard WooCommerce API callback endpoint:
INDEX_PHP?wc-api=pir_gateway(inferred action name). - HTTP Method: Typically
GETorPOST, depending on how the gateway handles the bank's redirection/callback. - Vulnerable Parameter:
MerchantReference(the WooCommerce Order ID). - Authentication: None required (Unauthenticated).
- Preconditions: An existing WooCommerce order must be in a state where it can be transitioned to "failed" (e.g., "pending" or "on-hold").
3. Code Flow (Inferred)
- Registration: The gateway class (likely extending
WC_Payment_Gateway) registers a callback via thewoocommerce_api_pir_gatewayhook (or similar slug) in its constructor:add_action('woocommerce_api_pir_gateway', array($this, 'check_piraeus_response')); - Entry Point: When a request hits
/?wc-api=pir_gateway, the handler (e.g.,check_piraeus_response()) is executed. - Order Identification: The handler extracts the order ID from the request, specifically using the
MerchantReferenceparameter. - Logical Flaw: The handler likely contains a conditional block for failed transactions (e.g., checking for a
ResultCodeorResponseCodeindicating failure). - Missing Check: In this failure branch, the plugin calls
$order->update_status('failed')without verifying that the request originated from the legitimate Piraeus Bank servers or that the request contains a valid cryptographic signature. - Sink: The WooCommerce database is updated, changing the order status to "failed" and potentially canceling stock or shipments.
4. Nonce Acquisition Strategy
This vulnerability resides in a payment gateway callback handler. These endpoints are designed to be called by external bank servers (Piraeus Bank), which do not have access to WordPress-generated nonces.
- Nonce Requirement: There is no WordPress nonce required for this endpoint.
- Authorization: The vulnerability exists specifically because the plugin fails to implement its own alternative to authorization (like signature verification) for the "fail" code path.
5. Exploitation Strategy
The goal is to move a "Pending payment" order to "Failed" status without being the customer or the bank.
Step-by-Step Plan
- Identify the Order ID: WooCommerce Order IDs are sequential. If a recent order was made, its ID can be guessed or identified (e.g., Order #123).
- Craft the Callback Request: Construct a request to the
wc-apiendpoint. - Trigger the Failure Branch: Based on the vulnerability description, the "fail" branch is the vulnerable one. We must provide parameters that lead the plugin to believe the transaction failed.
Exploit Request (Conceptual)
GET /?wc-api=pir_gateway&MerchantReference=123&ResultCode=1&Status=Fail HTTP/1.1
Host: target.local
(Note: Parameters like ResultCode and Status are inferred based on common Piraeus Bank API specifications and the vulnerability description. The primary identifier is MerchantReference.)
6. Test Data Setup
To verify this in the test environment:
- Install WooCommerce: Ensure WooCommerce is active.
- Install Plugin: Install and activate
woo-payment-gateway-for-piraeus-bankversion 3.1.4. - Create an Order: As a guest or customer user, add an item to the cart and proceed to checkout. Select "Piraeus Bank" as the payment method.
- Note Order ID: Capture the resulting Order ID (e.g., via the URL or the "Thank You" page).
- Verify Initial Status: Use WP-CLI to confirm the order is "pending":
wp wc order get <ORDER_ID> --fields=status
7. Expected Results
- The server should return a
200 OKor a redirect (depending on how the gateway handles the bank response). - The plugin will log a failure note on the order.
- The WooCommerce Order status will change from
pending(oron-hold) tofailed.
8. Verification Steps
After sending the HTTP request, verify the state change using WP-CLI:
- Check Status:
wp wc order get <ORDER_ID> --fields=status
Expected Output:failed - Check Order Notes:
wp wc order_note list <ORDER_ID>
Expected Output: A note indicating a failed transaction or payment error.
9. Alternative Approaches
If the wc-api action name is not pir_gateway:
- Discovery: Search the plugin source for
add_action( 'woocommerce_api_to find the exact slug registered. - Parameter Variation: If
ResultCodedoesn't trigger the failure path, examine the code for other parameters likeResponseCode,ResultDescription, orReasonCode. - POST Request: If a
GETrequest is ignored, attempt aPOSTrequest with the same parameters in the body:Content-Type: application/x-www-form-urlencodedMerchantReference=123&ResultCode=1
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.