During a recent cleanup for one of our clients, we found five administrator accounts that nobody on the team owned. The oldest dated back to March 2025. That's more than a year of full access that nobody had approved.
Most owners rarely open the Users screen, and too many sites give everyone the Administrator role to save time. WordPress user roles and permissions exist to stop that. Least privilege means every account gets only the capabilities its job needs.
This guide covers what each role can do, who should get which one, three places where roles carry more risk than they look, and a 20-minute audit you can run today.
What WordPress user roles and capabilities are
A role is a named bundle of capabilities. A capability is one permission, such as publish_posts or install_plugins. WordPress gives each account one role by default, and that role decides everything the account can touch.
A single site has five roles. Multisite adds a sixth, the Super Admin. WooCommerce adds Shop Manager and Customer.
One catch on the Editor row: Editors can still publish JavaScript by default. More on that below.
Which role should each person get?
Handing out Administrator feels reasonable. It's fast, and the freelancer asked for it. It also means one stolen password hands over the whole site, so match the role to the job instead.
The first row matters most. Malicious scripts run with the permissions of whoever is logged in, so a daily Editor account gives an attacker far less to work with. When in doubt, start one role lower and promote later.
Three places where lower roles carry more risk than they look
Editors can publish JavaScript by default
On a single-site install, both Administrators and Editors hold the unfiltered_html capability, which lets them add raw scripts to posts, pages and comments. Multisite removes it for everyone below Super Admin. If an attacker hijacks one Editor account, that script runs in front of every visitor. Add one line to wp-config.php and no role can do it:
.php
define( 'DISALLOW_UNFILTERED_HTML', true );
Some page builders need the capability, so test on staging first. We cover the attack itself in our XSS guide, and the wp-config fix in our wp-config hardening guide.
Contributor and Subscriber accounts aren't harmless
Patchstack's mid-year 2025 report found that roughly a fifth of vulnerabilities needed only a Contributor login and about one in nine needed only a Subscriber login. Core WordPress backs that up. Version 7.1 fixed several stored XSS bugs that needed nothing more than a Contributor account, plus an Author-level bypass of the safe-CSS filter. Version 7.1.1, released 17 September 2026, fixed eleven more issues, including a stored XSS that needed no login at all. Keep New User Default Role on Subscriber under Settings, General, and switch off Anyone can register unless the site needs signups.
↗️
Need Help Cleaning Your Site?
Our security experts remove malware, fix vulnerabilities, and protect your site.
Get Free Security Check
That last bug is the honest caveat here. Over half of all WordPress vulnerabilities need no login at all, so least privilege limits the damage a stolen account can do. It doesn't replace patching.
Some capabilities are administrator in disguise
If you build a custom role, never add install_plugins, edit_plugins, edit_users, promote_users, manage_options or unfiltered_html. Each one lets an account take over the site, either directly or in a couple of steps. manage_options alone can change the default role assigned to new signups. Our OWASP guide covers this whole class under Broken Access Control.
How to set up least privilege in five steps
Count your administrators. Go to Users and filter by Administrator. One or two real people is the target.
Downgrade each account to the lowest role that works. Log in as that user in a private window and check they can still do their job. Don't test by editing your own role. You can lock yourself out.
Build a custom role only where a default doesn't fit. Members, User Role Editor and Melapress Role Editor are free options. Clone Author or Editor and remove capabilities rather than starting from Administrator, and keep one untouched admin account as a fallback.
Lock two switches in wp-config.php. The first turns off the built-in theme and plugin editor. The second is the JavaScript fix from earlier.
php
define( 'DISALLOW_FILE_EDIT', true );
define( 'DISALLOW_UNFILTERED_HTML', true );
Our wp-config hardening guide covers the rest of the file. 5. Turn on two-factor authentication and an activity log. Require 2FA on every account at Author level or above. The log gives every role change a timestamp and a name.
How to audit your WordPress users in 20 minutes
Every guide tells you to review your users. Few show you how.
Read the Users screen. Go to Users and note the counts at the top, such as Administrator (2).
Ask WordPress from the command line.
bash
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
Compare the two. If the screen shows fewer administrators than the command does, an account is hiding. Some malware filters the Users list and even hooks WP-CLI, so the database is the source to trust most. phpMyAdmin doesn't run WordPress's PHP, so it can't be fooled the same way. Replace wp_ with your own table prefix.
sql
SELECT u.ID, u.user_login, u.user_email, u.user_registered
FROM wp_users u
JOIN wp_usermeta m ON u.ID = m.user_id
WHERE m.meta_key = 'wp_capabilities'
AND m.meta_value LIKE '%administrator%';
Flag what doesn't belong. Look for registration dates that match no hire, email addresses you don't recognise, and accounts with no posts and no logins. Ours dated back to March 2025, and an unknown administrator is one of the clearer signs a site's been compromised (our 19 Signs guide covers the rest).
Check application passwords. Run wp user application-password list <user> for each account that has one.
Preserve evidence, then remove. Export the rows and screenshot the Users screen first, then delete each account through WordPress and reassign its content.
bash
wp user delete <ID> --reassign=<ID>
Don't delete rows from wp_users by hand, since that orphans data in other tables. If a deleted account keeps coming back, something on the server is recreating it, and our investigation guide walks through tracing that.
Run a shorter version of this every time someone leaves:
Downgrade or delete the account and reassign its content.
Revoke its application passwords and rotate any shared logins.
Remove its access to hosting, Search Console, Analytics and DNS.
Give scripts and AI agents their own accounts
Application passwords, added in WordPress 5.6, let a tool call the WordPress REST API without your main password. They inherit the role of whoever owns them. They can't log in at wp-login.php, but they skip the interactive login entirely, so 2FA never gets a chance to ask for a code.
That makes the owner's role the whole security story. An n8n workflow or AI agent running on an Administrator credential can install plugins, edit users and change settings. Give each tool its own account instead:
Create a dedicated user, for example svc-n8n.
Set its role to Author if it only posts, or Editor if it also manages pages and comments.
Create one application password per tool and name it after the tool.
Revoke a tool's access by deleting its password, nothing else needs to change.

Md Azizul HakimSEO & Security Expert, AppDeel
Azizul Hakim is an SEO and website security specialist at AppDeel, the agency he founded and where he still handles client work himself. For more than ten years he has helped business owners and eCommerce brands get found in search and keep their websites secure.
Read more posts by Md Azizul Hakim →