Price Manipulation via Hidden Fields and Client-Trusted Totals
Hidden form fields still ship unit prices in 2026. So do JSON bodies with price, unit_price, amount, and total. If the server trusts those numbers, you set the sticker.
This is not clever crypto. It is a missing recalculation.
Intercept the money fields
Add an item, open the checkout request, and list every numeric field. Common offenders:
price/unitPricenext toproduct_idtotalcomputed in JavaScript beforePOST /checkoutdiscountortaxsupplied by the client- Multi-currency fields where
amountandcurrencytravel together
Change price from 49.99 to 0.01 or 1. Keep the product ID honest so inventory and fulfillment still make sense. If the payment provider charge matches your edited value, you have a finding. If the server ignores the field and charges the catalog price, move on—no need to pad the report.
I've seen apps that revalidate on the cart page but not on the final confirm call. Test both. Also replay an old cart token with a new price body; stale pricing sessions sometimes skip catalog lookups.
Totals, taxes, and "display only" lies
Some UIs mark the amount as display-only while still posting it. Others compute tax client-side. Drop tax to zero, flip currency to a cheaper unit without converting, or set quantity and price so the server multiplies your numbers instead of its own.
GraphQL mutations deserve the same treatment. A mutation like checkout(input: { items: [{ sku, price }] }) is an open invitation. Strip the price argument entirely once; if the backend errors, it expected the client value. If it succeeds with a lower charge after you lower the argument, document both responses.
Server-rendered order review pages that embed data-price attributes are not harmless. If the confirm POST rebuilds the charge from those attributes instead of the catalog, you still own the total—even when no classic hidden <input> exists.
Stay inside program rules. Prefer the lowest non-zero amount that still creates a paid order you can refund, or stop at a payment-intent preview that shows the charged amount without capturing funds.
Report with before/after money
Triage wants arithmetic, not vibes. Include:
- Unmodified checkout request and charged amount
- Modified request with the single changed field highlighted
- Payment or order receipt showing the attacker price
State that catalog price was never applied server-side. Suggest binding line items to SKU and server-side price lists, signing price quotes with a short TTL if offline quotes are required, and ignoring client totals completely.
If the store uses a third-party payment widget, check whether your tampered amount becomes the PaymentIntent amount. That is often where the bug actually lives—your app forwards the client total into Stripe or Adyen without a second look.
Mobile apps deserve a second pass. The web checkout may recalculate while the native client still posts a signed-looking price blob that is only Base64, not an HMAC. Decode it. If you can edit and re-encode without a server signature, treat that as the same class of bug.
Price manipulation is beginner-friendly and still pays when the charge is real. Edit one field. Prove the receipt. Stop.