Applying updates and checking for compromise are both essential, but there is a step before them: reducing how many ways in there are. This article lists five things to review to shrink a WordPress site’s attack surface: administrator accounts, file editing from the dashboard, file permissions, how
wp-config.phpis handled, and PHP execution under uploads. It pulls together earlier articles in this blog. None of these settings makes a site “secure”. They lower how easily things go wrong and how far damage can spread.
What an attack surface is
The attack surface is the total set of entry points and capabilities that can be reached from outside, or from inside once someone is in. The more there are, the more likely something is overlooked. Closing what you do not use makes the day an update arrives late less costly.
Narrowing the surface reduces the impact when a vulnerability is found; it does not remove the vulnerability. Updates and checks remain the main defense. The items below are supporting layers.
| Review | What it narrows | Related article |
|---|---|---|
| 1. Administrator accounts | How much power a stolen account holds | Compromise checks |
| 2. File editing in the dashboard | A route for rewriting code after an admin login | wp-config.php constants |
| 3. File permissions | What other users and processes on the server can see | Permissions and least privilege |
| 4. wp-config.php | Exposure of a file holding credentials | wp-config.php constants |
| 5. Code execution in uploads | Whether an uploaded PHP file can run | This article |
1. Keep fewer administrators
An administrator can install plugins, create users, and change settings. So the number of admin accounts is also the number of places where a takeover has full impact.
- Limit administrators to people who manage the site now. Remove or downgrade accounts of former staff and finished contracts
- Someone who only writes posts usually needs the Author or Editor role. Give the smallest role that covers the job
- Shared accounts hide who did what. Use individual accounts where you can
- Confirm the admin email address still receives mail, since it is part of the password-reset path
A read-only listing:
wp user list --role=administrator --fields=ID,user_login,user_email,user_registered
The test is whether you can explain, for every account, who it is and why it is an administrator. If one is unexplained, record it and investigate before deleting anything.
2. Turn off file editing in the dashboard
The WordPress dashboard can edit theme and plugin files in place. That is convenient, but it is also a route to rewrite server-side code for anyone who gets past the admin login.
Adding this constant to wp-config.php disables that editor:
define( 'DISALLOW_FILE_EDIT', true );
As covered in the wp-config.php constants article, this has few side effects if you do not edit code in the dashboard. A separate constant, DISALLOW_FILE_MODS, also blocks installing and updating plugins and themes. Check it against your maintenance routine first, because stopping updates would defeat the purpose.
3. Use the smallest file permissions that work
On Unix-like servers each file has read, write, and execute permissions for owner, group, and others. As the permissions article explains, the principle is the needed operations, for the needed parties, and nothing more.
- Avoid world-writable permissions such as
777unless there is a specific reason - Common starting points are
644for files and755for directories, but the right values depend on how PHP runs and who owns the files. Follow your host’s guidance - Record the current state before changing anything, so you can revert if something stops working
Checking is read-only:
find . -type f -perm -o+w -not -path "./wp-content/cache/*" | head -20
This lists files writable by “others”. Do not fix results mechanically; first work out why each one is that way.
4. Protect wp-config.php
wp-config.php holds the database credentials and the keys (salts) used by the login system. It is one of the files you least want read by others.
- Consider placing it outside the web root. WordPress can load it from one directory above the install. If your server layout allows it, that keeps it out of the public area. Take a backup first, since some setups break
- Tighten permissions along the lines above, so other users cannot read it.
600or640are common candidates, but some PHP setups need different values, so test after changing - Do not leave copies such as
wp-config.php.bakor.oldin a public directory. They are often less protected than the original - Rotate the salts when you review admins. Changing them invalidates existing login sessions
wp config shuffle-salts
Everyone is logged out afterwards, so pick the timing with care.
5. Do not let PHP run under uploads
wp-content/uploads/ stores media and is not meant to hold PHP code. If a PHP file lands there and can execute, a flaw in an upload path becomes far more serious.
The principle is simple: places for data should not execute code. How you do it depends on the server.
- On Apache, a
.htaccessfile in the uploads directory can deny PHP execution (Apache 2.4 example):
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
- On Nginx, configure the server so
.phpfiles under uploads are not passed to PHP - On shared hosting, whether
.htaccessis honored, and how, may depend on the control panel. Check your plan’s documentation
After any change, confirm that ordinary media such as images still display. Some plugins also keep their own PHP under uploads, so check that a deny rule will not break them.
To look for what may already be there, use the read-only commands in the compromise checks article.
Limits to keep in mind
- None of these fixes a vulnerability. They buy time when an update is late, but do not replace updating
- Settings can change behavior. Make one change at a time, after a backup, and record the state before and after
- Hosting differences are large. The values here are general guidelines and need checking in your environment
- This is not one-and-done. Staff changes and new plugins gradually widen the surface again, so review it regularly
Summary
- Narrowing the attack surface is a layer that limits damage on the day a vulnerability appears. It does not replace updates and checks
- Five items: number of admins, dashboard file editing, file permissions, wp-config.php, PHP execution in uploads
- Record the current state before each change and confirm behavior afterwards
- Values vary by environment. When unsure, rely on your host’s guidance or a specialist
One thing to do today: run wp user list --role=administrator and check whether any account is no longer in use.