One Web security task that slips through the cracks, even for experienced developers, is ensuring your forms originate on your server, through the use of a nonce, or a one-time, unique identifier for your form.
Why is this important?
- A favorite attack vector is to duplicate forms on a remote server, and attempt cross-site scripting (XSS) attacks that way. It’s far more convenient to me to write a curl routine that varies up the junk inputs I’m trying to run on my own server, than to run a bot that fills out the target form on its own host.
- Ensuring your form is submitted only once is most easily managed if you generate a unique identifier, created every time your form is created, and storing that identifier in some persistent data store; namely, a database, XML file or the like.
- A unique identifier for your form gives confidence your form contains what you expect. We can’t be absolutely sure that a properly formed nonce means your form is 100 percent pristine — we still need to check all inputs are present and contain what we expect — but we can usually begin our security checks by seeing if the nonce is present and well-formed, before doing things that constitute heavy lifting, such as sanitizing other inputs, doing calculations on them and rendering up a response or additional steps.
There are a lot of ways to create a nonce, and how best to proceed depends on what goal you have.
Sometimes, you just need to ensure the form originated on your site; it doesn’t need to be one-time use. Other times, you need to be absolutely certain the form is only submitted once. And occasionally, you need to time-limit when a form can be submitted.
I’ll start by addressing the middle requirement first: A one-time-use nonce, which isn’t time-limited (that is, the nonce can be used anytime, but once used, can’t be recycled). In upcoming blog posts, I’ll address the other two methods.