We’ve recently developed our own PHP NONCE library for use with custom programming. Our version is loosely based on the implementation found inside the core WordPress software.
What is an NONCE?
Literally, the term refers to a number used once. In software development, it is often used as a security measure to ensure that certain links or forms are only available once, thereby preventing malicious attacks against the system. Read More
Where would I use an NONCE
An NONCE offers an additional level of security where sensitive actions may take place within your application. Take the following line of code as an example:
<a href="delete_post.php?post=003">Delete Post</a>
This link was poorly thought out if the application has no other security measures in place. Anyone could begin deleting posts by simply pointing their browser at the above link and changing the post number.
Well designed applications would only make that link available if the user was logged into the system with appropriate permissions. Furthermore, the delete_post.php script would ideally check to see if the user was logged into the system and if the user had appropriate permissions to delete that post. Is this enough security though?
Here are just two scenarios that could circumvent the above security measures:
- Depending on how the application’s user authentication works, it is certainly possible for a malicious user to spoof an authenticated user or to otherwise crack the authentication.
- Additionally, if you are a legitimate admin of the above mentioned application it would be possible for me to trick you by sending you a link or to this script. Once you clicked it, the post would be deleted.
How an NONCE prevents the above attacks
An NONCE is successful as an additional layer of security because it prevents actions initiated by links or REQUESTS from being used more than once. Every time a link or a form is printed on the screen, your NONCE functionality embeds a key / value pair to be sent to the receiving script. Every time that script is called, it checks for the key / value pair and then authenticates it on a pass / fail basis. If it passes, the action is performed, if it fails, the action is not performed.
The above link with an NONCE applied to it would resemble something like the following:
<a href="delete_post.php?post=003&_nonce=9c5fbfabb1">Delete Post</a>
The receiving script would then do the following:
- Check to see if the user is logged in with appropriate permissions (standard security)
- Check to make sure the NONCE key / value is set
- Authenticate the received NONCE using a library of functions.
How does an NONCE create and authenticate its key / value pairs?
While there are no hard and fast rules for creating an NONCE, most libraries will include the following components when generating an NONCE:
- A secret key or ‘salt’ stored only on the server
- A user ID (optional – makes the NONCE only work with a specific user)
- An action name: ie: ‘delete-post’
- A timestamp (allowing the NONCE to expire if never used)
- A database of used NONCEs (optional and not used in our library)
Using all of the above components, an NONCE may be generated like this: secret-salt + user ID + action-name + timestamp. All of this is thrown into a hash that the receiving script can unpack and authenticate (Most of the time, the timestamp will be modified before being included and hashed).
The receiving script doesn’t actually ‘unpack’ the received key, rather it recreates it and compares. For instance, the delete_post script would combine the secret salt (which it knows) , the current users’s ID , use the delete-post action name, and a timestamp (modified appropriately). If any one of those components are off, the NONCE value generated by the receiving script will not match the one sent by the initial script and the NONCE will fail to authenticate.
How to use our NONCE library
- Download the zip file and unpack
- Include ft-nonce.php inside all your applications pages
- Embed one of our two generating functions in your links or forms
- Call the validating function at the top of your receiving scripts and do as you wish based on the validity of the NONCE.
If you need further example, you can check out the example here. The PHP file source file is included in the zip .
We’ve only deployed this once and value your feedback. We will be more than happy to modify, enhance, and correct bugs as reported.