Using Nonces to Strengthen WordPress Security
Using Nonces to Strengthen WordPress Security
WordPress security is a hotly debated topic and as I mentioned in my WordPress Ain’t Perfect article a while back, it mostly comes down to issues with plugins and themes, not WordPress itself.
Nonces are one of the best ways to protect users from possible threats. They are used to secure user actions initiated by the plugin such as the submission of a form, the deletion of post or anything else that could expose the database.
In this Weekend WordPress Project I’ll describe the problem nonces are meant to solve and how you can use them to make your products more secure.
Why We Need Nonces
Let’s say you’re writing a plugin that allows the user to delete a post from the front-end. For the sake of simplicity the mechanism to delete a post is a link that takes you to
http://mysite.com/2015/02/12/my-article/?delete=true. In other words, the link to the article with a query string attached.
The code you implement on that page checks if the user is an admin and if so, the post is deleted, the user is redirected back to the main page.
This seems safe right? After all, you did check if the user was an admin right?
Sadly, this isn’t enough. There are two things you need to check before each action is taken: permission and intent.
You have checked that the user has permission, but you can’t be sure the user actually does want to delete the post.
Imagine I sent you an email saying I found a typo in one of your posts and I link it in. If I create a link in an email you won’t see the target, just the clickable text. So if I append the
?delete=true string to the end you will end up deleting the post, even though you never meant to.
This is where nonces come in. A nonce is a special code that gets generated at the source of the action. When using a nonce the link may look something like this:
http://mysite.com/2015/02/12/my-article/?delete=true&_wpnonce=234283223. Since the nonce will always be different I won’t be able to send you a simple link since the deletion process won’t work without the correct nonce.
What Are Nonces Anyway?
Nonce are short for “number used once,” and they are used in cryptography for securing data by sending a one-time numeric code next to them.
WordPress implements nonces a bit differently because they are neither numbers nor used only once but their purpose and use is very close. WordPress uses a hash and nonces can sometimes be used more than once, they have a short expiration time.
Using WordPress Nonces
The process is a fairly simple two-step affair: You generate a nonce at the origin of an action (placing it in a link or as a hidden field in a form) and validate it at the target. You’ll only need to know a couple of functions, here goes:
Adding Nonces to Forms
To add a nonce to a form you’ll need to add a hidden field with a name and a value. WordPress has you covered with the
In its most simple form you can use it with just one parameter:
This would create two fields for you, one for the nonce and one for a referrer, which WordPress can also check.
The function actually gives you four parameters to let you fine tune. The first parameter defines the action that is taken with the nonce. This doesn’t show up in the field, it is contained in the hash. The second parameter modifies the name, which is
_wpnonce by default. The third parameter is a boolean value which controls whether or not the referrer is checked (true by default). Finally, the fourth is a boolean which determines whether or not the field is echoed – it is true by default.
One important rule to follow: Always make the action name (the first parameter) as specific as possible. Don’t just name it “delete-post”, make it “delete-post-[post_ID].
On the other end of the action you’ll need to verify the nonce. This would be where the form’s action parameter takes you. To verify the nonce use this simple code:
Note that this will only work if your form uses the
post method. You really should be using
post for anything sensitive though.
Adding Nonces To URLs
Sometimes you want to initiate an action through a link, especially in the admin area. Since links are essentially passed on as query parameters you can easily tack them on to links as well.
You can use the
wp_nonce_url() function to get this one done. Here’s how.
The end result will be a URL that looks something like:
http://mysite.com?p=553&_mynonce=7278c82a8f3. As you can see this is very similar to what we did with forms, the only difference is that the nonce is passed in the URL as
You can verify the nonce using much the same method as before. This time let’s add the proper action name with the ID and use
That was pretty simple wasn’t it? And it adds a big layer of security to your product.
Nonces should really be used any time you want to initiate a user action otherwise your application is vulnerable to all sorts of attacks.
Don’t forget that nonces only check for intent. You’ll still need to make sure the user has the proper permissions as well.
Have any other ways of securing your work? Do you find nonces to be awesome like I do? Let us know in the comments below.
Image credit: Pixabay.