CVE-2025-14460

Piraeus Bank WooCommerce Payment Gateway <= 3.1.4 - Missing Authorization to Unauthenticated Arbitrary Order Status Change

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.1.5
Patched in
9d
Time to patch

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: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<=3.1.4
PublishedJanuary 6, 2026
Last updatedJanuary 15, 2026

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

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 GET or POST, 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)

  1. Registration: The gateway class (likely extending WC_Payment_Gateway) registers a callback via the woocommerce_api_pir_gateway hook (or similar slug) in its constructor:
    add_action('woocommerce_api_pir_gateway', array($this, 'check_piraeus_response'));
  2. Entry Point: When a request hits /?wc-api=pir_gateway, the handler (e.g., check_piraeus_response()) is executed.
  3. Order Identification: The handler extracts the order ID from the request, specifically using the MerchantReference parameter.
  4. Logical Flaw: The handler likely contains a conditional block for failed transactions (e.g., checking for a ResultCode or ResponseCode indicating failure).
  5. 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.
  6. 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

  1. 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).
  2. Craft the Callback Request: Construct a request to the wc-api endpoint.
  3. 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:

  1. Install WooCommerce: Ensure WooCommerce is active.
  2. Install Plugin: Install and activate woo-payment-gateway-for-piraeus-bank version 3.1.4.
  3. 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.
  4. Note Order ID: Capture the resulting Order ID (e.g., via the URL or the "Thank You" page).
  5. 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 OK or 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 (or on-hold) to failed.

8. Verification Steps

After sending the HTTP request, verify the state change using WP-CLI:

  1. Check Status:
    wp wc order get <ORDER_ID> --fields=status
    Expected Output: failed
  2. 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 ResultCode doesn't trigger the failure path, examine the code for other parameters like ResponseCode, ResultDescription, or ReasonCode.
  • POST Request: If a GET request is ignored, attempt a POST request with the same parameters in the body:
    Content-Type: application/x-www-form-urlencoded
    MerchantReference=123&ResultCode=1

Check if your site is affected.

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