E-commerce platforms often implement small convenience fees to cover operational costs such as logistics processing, payment handling, or platform services. These fees are typically applied automatically during checkout and are expected to be enforced server-side.

While exploring Nykaa's checkout workflow, I discovered that the convenience fee mechanism relied on a client-controlled flag, which could be manipulated to bypass the fee entirely. By modifying a request header or payload field, it was possible to remove the cart charge before placing an order.

This write-up explains how the issue works, how it can be reproduced, and why relying on client-side logic for pricing controls can lead to business logic vulnerabilities.

Nykaa's checkout APIs rely on a parameter called:

X-APPLY-CART-CHARGES: true

or in some endpoints:

"applyCartCharges": true

This flag determines whether the platform/convenience fee (₹9 — ₹99 depending on order value) should be applied to the cart.

However, the server trusts the value supplied by the client.

By intercepting requests during checkout and modifying this parameter from true → false, the convenience fee can be removed from the order.

This creates a business logic flaw where the client can decide whether platform charges should be applied or not.

Initial Discovery

The issue surfaced while analyzing the checkout process and observing API traffic using an interception proxy.

During reward point application, I noticed the following endpoint:

POST /gateway-api/cartapi/v1/reward/apply

The request included a header:

X-APPLY-CART-CHARGES: true

This immediately raised a question:

Why should the client control whether platform fees are applied?

Normally, pricing logic must be calculated and enforced entirely server-side.

This led to testing what would happen if the header was modified.

Digging Deeper

To understand what the header actually controlled, I started replaying the request while observing how the cart responded.

First, I applied reward points normally.

The intercepted request looked like this:

POST /gateway-api/cartapi/v1/reward/apply
X-APPLY-CART-CHARGES: true

I forwarded the request without modifying anything.

The result was exactly what I expected:

Total price updated
Reward discount applied
Convenience fee still present

Everything looked normal.

But now it was time to change something.

The First Experiment

Before forwarding the request again, I modified the header:

X-APPLY-CART-CHARGES: false

Then I sent the request to the server. The request succeeded. But the cart total looked different. The convenience fee had disappeared.

At that moment it became clear:

The backend was trusting a client-controlled value to decide whether platform charges should apply.

Confirming the Behavior

To ensure this wasn't just a temporary cart calculation issue, I repeated the process several times:

  1. Apply reward points normally
  2. Remove reward points
  3. Reapply them with the modified header.
  4. Every time the header was set to:
X-APPLY-CART-CHARGES: false

the cart charges vanished.

The behavior was consistent and reproducible.

Expanding the Investigation

After confirming the issue in the reward endpoint, I continued exploring the checkout flow.

Soon I found the same parameter in another API call used during address confirmation.

POST /fe-api/cartapi/v2/address/add

Once again the request contained:

X-APPLY-CART-CHARGES: true

At this point it became clear that the parameter was embedded throughout the checkout flow.

Which meant the vulnerability likely extended beyond just reward points.

Real Order Demonstration

To test the issue in a real checkout scenario, I selected a simple product.

Product: Minimalist 2% Salicylic Acid + LHA Face Cleanser Price: ₹299

None

After adding it to the cart, the price breakdown appeared as expected:

Product Price  → ₹299
Cart Charges   → ₹9
Total          → ₹308
None

So the system was clearly applying the convenience fee.

Now it was time to remove it.

Intercepting the Address Confirmation Request

During checkout, when clicking Deliver Here, the following request is triggered:

POST /fe-api/cartapi/v2/address/add

The request contains:

X-APPLY-CART-CHARGES: true

I modified it to:

X-APPLY-CART-CHARGES: false

After forwarding the request, the cart refreshed immediately.

The new price became:

₹289

The ₹9 convenience fee was removed.

Completing the Checkout

The final test was to see whether the order could actually be placed with the modified price.

Two payment flows were tested:

UPI Payment

The QR code generated during checkout reflected the updated price:

₹289

Cash on Delivery

During order placement, another parameter appeared in the payload:

"applyCartCharges": true

After changing it to:

"applyCartCharges": false

the order was successfully placed.

Final payable amount:

None
₹289

Final Thoughts

Business logic vulnerabilities rarely involve complex exploits.

Sometimes the entire issue comes down to something as simple as trusting the wrong input.

In this case, a single client-controlled flag was enough to bypass a pricing rule inside the checkout system.

This research highlights an important principle in application security:

Anything related to money should never be controlled by the client.