This has been stressing me out.. I have a hidden input:
<input type="hidden" value="North Miami" name="city">
Server-side only. The easiest way to do this is to use session variables (like
$_SESSION) so that all the data kept on the server side, but managing it and keeping separate tabs a user might have open separate can get a little tricky. This option prevents the user from seeing or editing the information.
Make the client carry an encrypted blob. Take all your "temporary but protected" data, combine it somehow (e.g. JSON) and then encrypt* the whole thing with a secret key known only to the server. Base64 the result and put that into the hidden field value. (Note that for a high-security application, you'll also want to work an HMAC into this process, which validates that the ciphertext hasn't been tinkered with.) This option also prevents the user from seeing or editing the information, but makes it easier to handle cases where one user has many tabs open.
Still use not-so-secret hidden input fields, but add an anti-tampering mechanism. So when the page is being generated, take all of your existing "protected" variables, combine them somehow with a server-side secret value, and hash [correction: HMAC] them. Store the hash in its own hidden field. Then after the user submits, you repeat the process and check if the hash matches. If it doesn't, have everything error with security-violation page.
*As with all cryptography, doing this the "right" way can be tricky and depends a lot on how you encrypt/verify. There are lot of pitfalls in terms of ciphers and cipher-modes etc.
Finally, remember that preventing people from modifying it doesn't mean a user can't copy everything and re-use it later or under another account, unless you take steps to include a "timestamp" etc.