When talking about WordPress security from a developer’s standpoint, it’s inevitable that the topic of nonce fields and nocne values are going to come up. And rightfully so! These are ways to help protect submission information from contaminating our databases.
But are they the way to fully secure our code? Before looking at that, I want to make sure we’re all on the same page as to what a nonce value is. When you look through enough WordPress source code (well, source code in plugins, etc.) then you’re likely to find some developers don’t use them (though they should).
A nonce is a “number used once” to help protect URLs and forms from certain types of misuse, malicious or otherwise. WordPress nonces aren’t numbers, but are a hash made up of numbers and letters.
Nor are they used only once, but have a limited “lifetime” after which they expire.
During that time period the same nonce will be generated for a given user in a given context. The nonce for that action will remain the same for that user until that nonce life cycle has completed.
Though this is the gist of it, there’s more to it than that, and I highly recommend reading the Codex article as it does a good job of outlining what they are, how to use them, and what their purpose is when working with them.
The question remains, though: Are nonces enough when it comes to WordPress Security?
WordPress Security: Nonce Values
First, I admit, WordPress Security is a multi-faceted term, and I don’t mean to generalize it as such in this post. Instead, this is but one aspect, and it’s one that we, as developers, should know how to implement.
We should also know how to add additional security measures, as well such as methods like current_user_can(). But I digress on that for now.
In my attempt continue sharing resources I think are very pertinent to what we do for a living, I wanted to highlight a post by Gennady Kovshenin that aims to cover the vulnerabilities of using nonces (and how to improve upon it):
WordPress Plugin Developers: please, please, please, always protect your functions using current_user_can. Nonces are not designed to secure access around your functionality, their purpose is to protect against CSRF exploits.
A heads-up: If you’re like me, you’re not a big fan of calling out plugins that are doing something wrong in a public manner. These types of things should be disclosed in private.
If you continue to read the article, Gennady does the responsible thing. He waits until the problem is solved before using it as an example. That’s mature discussion, in my opinion. More people should follow this example.
Anyway, the next time you’re working with nonce values and you want to make sure that your code is as secure as it can be, please remember to do more than just use nonce values.
Checking for permissions is good, checking for nonces is good, checking for them both is great.