WordPress Security

WordPress User Roles and the Principle of Least Privilege

What each WordPress role can really do, which capabilities carry the risk, how to audit the accounts you already have, when a custom role makes sense and how to offboard people cleanly.

WordPress User Roles and the Principle of Least Privilege

WordPress user roles exist so that a writer can write and a shop assistant can ship orders without either of them being able to install a plugin. On most sites we audit they are barely used. Nearly everyone is an Administrator, because that was the quickest way to make a permission error go away. It works until one of those accounts is phished and the attacker inherits the right to install plugins and create users.

Least privilege means every account gets the access its job needs and nothing above that. Putting it into practice takes three things: knowing what each role really allows, knowing which capabilities carry the risk, and tidying up the accounts you already have.

What the built-in WordPress user roles allow

RoleCanCannot
SubscriberLog in and manage their own profileCreate or edit content
ContributorWrite and edit their own postsPublish them or upload files
AuthorPublish and manage their own posts, upload mediaTouch anyone else's content
EditorPublish and manage all posts and pages, moderate comments, manage categoriesChange settings, plugins, themes or users
AdministratorEverything on the siteNetwork-level tasks on multisite

A role is only a named bundle of capabilities, such as edit_others_posts or manage_options. WordPress checks the capability, never the role name, when it decides whether to allow an action. On a multisite network there is one more level, the Super Admin, and site administrators there lose the ability to install plugins and edit users. The full matrix is in the official Roles and Capabilities documentation.

The capabilities that carry real risk

Most capabilities are about content. A handful decide whether a stolen account is an annoyance or a takeover.

  • install_plugins, edit_plugins and edit_themes amount to running your own PHP on the server. Whoever holds them controls the site and its data.
  • create_users, edit_users and promote_users allow an account to create a new administrator or raise an existing user to one.
  • manage_options opens every settings screen, including the site address, the admin email, and whether anyone can register and with which default role.
  • unfiltered_html lets a user save raw HTML, scripts included, in posts and pages. On a single site, Administrators and Editors both have it. WordPress treats this as intended behavior for a publishing tool, but it means an Editor account is not low risk: whoever takes it over can put a script on pages your visitors load.
  • upload_files starts at Author. WordPress restricts the file types, and plugins sometimes widen them.

The practical lesson is that two-factor login belongs on Editors as well as Administrators, and that "make them an admin" should be a deliberate decision each time. Our guide to securing the WordPress login covers the options.

Roles that plugins add

Plugins register their own roles, and their names tell you little. WooCommerce adds Customer, who can see their own account and orders, and Shop manager, who can manage products, orders, coupons and WooCommerce settings, edit customer accounts and work with posts and pages like an Editor. Learning plugins add instructor and group leader roles. Membership, forum and SEO plugins bring more.

Check what each added role can do before you hand it out:

wp role list
wp cap list shop_manager

Roles are stored in the database, so they outlive the plugin that created them. After removing a plugin, look for roles it left behind and for users still assigned to them.

Audit the accounts you already have

  1. List the administrators. Go to Users > All Users and click Administrator, or run wp user list --role=administrator --fields=ID,user_login,user_email,user_registered.
  2. Put a name and a reason next to each one. Is this person still with you or still working for you? Do they change settings or install plugins as part of their job? Someone who only publishes should be an Editor or an Author.
  3. Look for the odd ones. Accounts on generic addresses such as info@, accounts with no role, role names you do not recognize and registration dates that match no hiring or project.
  4. Check the registration settings under Settings > General. "New User Default Role" should be the lowest role your site uses.
  5. Open each administrator's profile and review the Application Passwords section. Revoke entries nobody can explain.
  6. Set a rule and write it down. A small business rarely needs more than two or three administrators: the owner, the person or agency responsible for the site, and a spare account for emergencies.

The Users screen does not show when somebody last logged in. An activity log plugin fills that gap and makes the next audit much faster. Administrators who also write content can keep a second, lower-level account for daily work, so the powerful login is used only when it is needed.

When to create a custom role

The built-in roles do not cover every job. Typical gaps are "can edit and publish pages but cannot paste scripts", "can read form entries and nothing else" and "can manage menus but not plugins". You can fill them with a role editor plugin or with a few lines in a small plugin of your own:

function myprefix_add_content_manager_role() {
    add_role(
        'content_manager',
        'Content Manager',
        array(
            'read'                 => true,
            'edit_posts'           => true,
            'edit_others_posts'    => true,
            'edit_published_posts' => true,
            'publish_posts'        => true,
            'edit_pages'           => true,
            'edit_others_pages'    => true,
            'edit_published_pages' => true,
            'publish_pages'        => true,
            'upload_files'         => true,
        )
    );
}
register_activation_hook( __FILE__, 'myprefix_add_content_manager_role' );

Three things about this example are deliberate. The role is added on plugin activation, because roles are saved in the database and do not need to be registered on every page load. It has no unfiltered_html, so WordPress strips scripts and other unsafe markup from whatever these users save. Test that with your page builder, since some embeds rely on markup that gets removed. And it has no delete capabilities, so these users cannot remove content.

If the role already exists, add_role() does nothing. To change it later, use get_role( 'content_manager' )->add_cap( 'moderate_comments' ). In your own code, always test a capability with current_user_can() and never compare role names, so that custom roles keep working.

Offboarding and shared logins

When someone leaves, or an agency's contract ends, close their access the same day. In WordPress, delete the account or set its role to none. Deleting asks what to do with the user's content: choose "Attribute all content to" another user, or their posts go with them. From the command line, wp user delete 12 --reassign=5 does both steps for user 12.

WordPress is only one of the doors. The same person may have a hosting panel login, SFTP or SSH keys, database access, the domain registrar, the CDN, analytics and tag manager, the payment provider and the email marketing tool. Keep a list of every system that touches the site, so that offboarding is a checklist and not an act of memory. Change any shared secret they knew.

That last point is the case against shared logins. An account used by five people cannot be traced to one of them, cannot be closed for one of them, and has a password that travels through chat and email. WordPress user accounts cost nothing, so give every person their own, including each person at your agency.

Where roles stop being a settings job

Auditing accounts and downgrading roles needs no developer. Code becomes necessary when permissions depend on ownership or context, and not only on the type of content: instructors who may see only their own students, branch managers who may edit only their branch's listings, vendors on a marketplace. A role alone cannot express those rules. They need capability mapping in a plugin, and tests to prove nobody can reach a neighbor's data.

That is the kind of work we do in WordPress development projects, most often on membership sites and learning platforms where roles decide what people have paid to see. For the wider picture, the user checks here are the first group in our WordPress security checklist.

Frequently asked questions

What is the difference between a role and a capability?

A capability is permission to do one thing, such as publishing a post or installing a plugin. A role is a named set of capabilities that you assign to a user. WordPress decides what someone may do by checking capabilities, which is why a custom role works anywhere a built-in one does.

How many administrators should a WordPress site have?

As few as the work allows, and at least two. A single administrator is a lockout waiting to happen when that person loses a phone or leaves. Beyond the people who really manage settings and plugins, plus one emergency account, everyone else is better served by a lower role.

Can I give someone access to just one page or one section?

Not with the built-in roles, which apply to a whole content type across the site. Restricting a user to particular pages or categories takes a plugin built for that purpose or custom code that maps capabilities per item. Test the result by logging in as that user before relying on it.

Do customers on a WooCommerce store count as users?

Yes. Each registered customer is a WordPress user with the Customer role, able to see only their own account and orders. They are still logged-in users, which matters when a plugin vulnerability is described as needing an authenticated account: on a store, anyone can create one.

Add WorldWin Coder to your preferred sources

Add worldwincoder.com as a preferred source on Google, or open this article in your AI assistant to use it as a source.

Swati Priyadrshni
· Founder & CEO at WorldWin Coder

I'm Swati Priyadarshani, Founder & CEO of LMS Advisor and Co-Founder of WorldWin Coder Pvt. Ltd. (est. 2019). Over the last 10+ years, I've helped enterprises build learning platforms that actually get used - not just deployed.

Keep reading

Have something to build, fix or move?

Tell us where you are. A developer reads every inquiry, and you get next steps and a free quote within one business day.