Yaamlabs
Case study 05

Client-side price on a booking flow

Booking and marketplace

A booking platform sold access to premium workspace by the hour. We were asked whether the price a member paid was the price the server set, or the price the browser sent.

Web & API penetration test, Workspace booking platform, severity HIGH, reported 2023

At a glance

  • Challenge. A booking flow charged the price the browser sent rather than a price the server recalculated from the room and the hours booked.
  • Approach. We booked a premium space, saw the amount came from the request, changed it, and completed a booking recorded as paid in full.
  • Result. Pricing is now computed on the server from the booked item and duration, discounts validated server-side, then the flow was retested.
  • Impact. A member could set their own price and complete a booking the platform recorded as paid in full, a quiet and continuous loss of revenue.
  • Classification. CWE-602 Client-Side Enforcement of Server-Side Security, OWASP Top 10 (2021): A04 Insecure Design. Component: Booking price calculation.

The challenge

A price shown in a browser is a display. A price sent from a browser is a suggestion. Trouble begins when the server accepts the suggestion as the amount to charge, because the browser is the one place in the system the customer fully controls.

The interface makes this hard to see. The member picks a room, the total updates, the total is charged. Everything on screen agrees. What is not on screen is that the total travelled to the server and back, and could be edited on the way, and the server never recomputed it from the room and the hours it actually booked.

The result is a shop where the customer writes the price tags. Nothing looks broken, because every booking is internally consistent. The loss is quiet and continuous.

Our approach

We booked a premium space and watched where the price was decided. When the amount charged came from the request rather than from the server's own calculation, we changed it and completed a booking that the platform recorded as paid in full.

Around that we checked the surface that shared the assumption:

  • Whether the charged amount was recomputed on the server from the booked item and duration
  • Whether discount and credit codes were validated server-side or trusted from the client
  • Whether currency and quantity fields were bounded and checked
  • Whether the same pattern reached upgrades and add-ons

Delivered with the request sent and the booking it produced, so the finding could be reproduced against a test account without taking our word for it.

From finding to fix

  1. Followed where the price was decided
  2. Sent a lower amount than the room cost
  3. Completed a booking marked paid in full
  4. Moved pricing to the server, retested

The outcome

Pricing is now computed on the server from the booked item and duration, so the amount in the request is ignored. Discounts and credits are validated server-side, and quantity and currency are bounded.

We retested the booking and upgrade flows after the fix. Reported as HIGH in 2023. Retest included in the engagement.

Check your own system

  • Recompute every charge on the server from the booked item and duration, and ignore any amount sent by the client.
  • Validate discount and credit codes server-side rather than trusting a total the browser supplies.
  • Bound and check quantity and currency fields so they cannot be pushed outside sensible limits.
  • Apply the same server-side pricing to upgrades and add-ons, not only the main booking.

Read more case studies, see Web Application Penetration Testing, or write to hello@yaamlabs.com.