This blog post is about the difference between authentication and authorization and provides some tips for bug hunters and developers alike to better understand how it is handled in WordPress.
The difference between authentication and authorization
Let’s talk about authentication vs authorization, in that order, because that is the order they happen.
First, you authenticate, then you check what the authenticated users are authorized to do, and you must do both.
Authentication vs authorization sounds a lot alike which may be why it is a common point of confusion, even in enterprise application development. So, let’s get into the differences.
What is authentication?
The difference between authentication and authorization is that authentication solves the problem of identifying who is making this request to the application. Authentication confirms Identity.
What is authorization?
Authorization, on the other hand, solves the problem of “now that we know who this user is, are they allowed to take this action?”. Authorization confirms Permission.
So, let’s go back to Authorization or permission.
Authentication or identification is commonly done via an initial challenge, matching a username with a password being the most common, then maintained through sessions or temporary authentication tokens. Once persisted, your application can be sure it knows which user is interacting with the application.
So, now all you need to solve is “Should we allow this user to take this action?”
Within WordPress, they use Roles and Capabilities to manage a list of capabilities a user is authorized or permitted to take. Each user account is assigned to a role, you may already know a few like Author and Administrator, but WordPress also supports custom roles. And each role is mapped to a list of capabilities users with that Role can take.
A full list of the default roles and capabilities included in WordPress core can be found here: https://wordpress.org/support/article/roles-and-capabilities/
So, now you know a user gets assigned a role, and a role has a set of capabilities or actions they can take. How do you look this up?
Luckily WordPress core made this easy, call the current_user_can( … ) function, In its simplest form, you can call current_user_can() and pass it a capability like current_user_can(“manage_options”), and the function will return true or false if the current logged in user has permission or authorization to manage the options table in WordPress.
And that, in short, is authorization in WordPress.
Now, when should you check this?
Every time you are executing code that is protected, especially in requests to action hooked to functions that are handled by the WordPress API.
So, if you have added a function as a hook using add_action((“hook_name”, “callback_function”) then within the callback_function is where you should be performing authorization checks using current_user_can().
Let me mention a common function or a gotcha in WordPress too. The function is_admin() sounds like it checks if the user is an administrator, and I have seen developers trying to use it in this manner before, but the is_admin() function only checks if the URI includes /wp-admin/ in the path, that is not authorization!
Plus, let us unpack this a little more: Even if this functioned how it is incorrectly assumed to work (is the user an admin?) checking a user’s Role is not checking that Role’s capabilities. So, in the end, if you are looking to check if a user is authorized to perform an action, please use current_user_can() are your go-to function.
By the way! It is also important to add a nonce check as well.
Now you know the difference between authentication and authorization!
There are many ways you can configure and customize your website to take security to the next level. One way to is to do some website hardening.
You can set your own firewall rules and tweak some settings here and there – for example – set a custom WordPress login URL or block certain countries from accessing your site.
You can also learn what is vPatching and why it is an essential part of security for a WordPress website.