Why is putting state like a price in a hidden form field a security flaw, and what's the correct fix?
A hidden field is just HTML — the browser will dutifully send back whatever the client edited it to. An attacker can change price=5.50 to price=0.50 with browser dev tools and the server, trusting the value, will bill them 50¢ for the socks.
The broken pattern:
<input type="hidden" name="price" value="5.50">
if (pay == yes && price != NULL) bill_creditcard(price); // BUG: trusts client price
The flaw: "hidden" only means the user doesn't see it on the rendered page. It is not "hidden from the network" or "tamper-proof." F12 → edit value → submit. Done.
The fix — keep authoritative state on the server, send only an opaque reference:
<input type="hidden" name="sid" value="781234"> <!-- large random session id -->
price = lookup(sid); // server's own price for this session
if (pay == yes && price != NULL) bill_creditcard(price);
Now the client can change sid all they like — at worst the lookup fails. The price was never theirs to set.
This is an OWASP A5 — Broken Access Control issue: trusting a client-supplied value as an authorisation decision.
Tip: Same rule for cart totals, discount percentages, user IDs, role flags, "is_admin" anywhere on the client. The server's view of state is the only one that counts.