Securing Your WordPress Plugin: Nonces

So you’ve created an epic contact form plugin for your WordPress install.  It seems secure enough.  You’re validating input, checking input types, and doing everything else right.  After it’s been up for a few weeks, you take a look at your database and notice you’ve got a bunch of crap in there.  “How could this happen?!” you scream!

Well, it probably had something to do with a Cross Site Request Forgery (CSRF).  Cross site request forgeries happen when someone starts submitting information to your form’s processing controller from another domain.  This is easy enough to do, because you can set the action field of a form to anything you want.  If you aren’t careful how you process your form, CSRF attacks can be a huge problem.   So how can you secure your plugin against CSRF attacks?  By using a nonce (Number used once).

Nonces are unique identifiers that you can use to make sure your form is coming from the right place.  To use them, you follow three simple steps.

  1. Create the nonce identifier. (wp_create_nonce)
  2. Place the identifier in your form or query string.
  3. Verify that the nonce is correct. (wp_verify_nonce)

In practice, it looks something like this.

1
2
$nonce = wp_create_nonce("my-plugin-nonce");
echo "<a href='controller.php?nonce={$nonce}'>Click here!</a>";

And then in your controller/processor…

1
2
$nonce = $_GET['nonce'];
if(!$wp_verify_nonce($nonce, "my-plugin-nonce")) due("No CSRF for you!");

That’s really all there is to it.  In literally 4 lines of code, you can make your plugin that much more secure.  On a side note, if you are using ajax to submit a form or pull data, you can pass the nonce through as a form field (or as part of the query string), but you’ll need you use a different function to verify it (check_ajax_referer).

1
check_ajax_referer("my-plugin-nonce");

Additional Resources