Upsell Funnel Builder for WooCommerce – Create Upsells, Cross-Sells, Order Bumps, Frequently Bought, and Popups. <= 3.1.4 - Missing Authorization
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:NTechnical Details
<=3.1.4What Changed in the Fix
Changes introduced in v3.1.5
Source Code
WordPress.org SVN# 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 potentiallyadd_cart_discount_offer_in_cart) - Method: POST
- Authentication: Unauthenticated (
noprivAJAX 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
- Registration: The plugin initializes
Upsell_Order_Bump_Offer_For_Woocommerce_Public. - Hooking: Inside the public class, the action
wp_ajax_nopriv_add_to_cart_fbt_productis hooked to a handler function (e.g.,wps_ubo_add_to_cart_fbt_product). - 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. - Processing: The PHP handler (located in
public/class-upsell-order-bump-offer-for-woocommerce-public.php) receives the POST data. - Sink: The handler likely calls
WC()->cart->add_to_cart()or a similar function, passing thewps_discount_pricedirectly 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:
- 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. - Page Creation: Create a test environment page:
wp post create --post_type=page --post_status=publish --post_content='[wps_bump_offer_shortcode]' - Extraction:
- Navigate to the page.
- Use
browser_evalto 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.phpviawp_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:
- Discovery: Identify a valid product ID (
wps_product_id). - 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
- URL:
- Verification: Observe the response. A success response (
{"success": true}or similar) suggests the product was added.
6. Test Data Setup
- WooCommerce Installation: Ensure WooCommerce is active.
- 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 - 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
- Check Cart via Browser: Navigate to
example.com/cartand verify the product price. - Check Cart via CLI:
Since cart data is session-based, browser verification is preferred. However, one can check the WooCommerce logs or thewp_woocommerce_sessionstable 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 inpublic/js/wps_ubo_lite_public_cart_script.js) also takes a price parameterwps_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 usingbrowser_eval("wps_ubo_lite_public_cart.auth_nonce").
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
@@ -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'; +#: 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.