Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild

How to Protect WordPress Files: Permissions, wp-config, and the Editor You Should Disable

Sean

Platform Writer

Aug 17, 2026
9 min read

Four changes cover most of the file-level risk in a WordPress install: correct permissions, wp-config.php unreachable over HTTP, the dashboard file editor turned off, and PHP execution blocked inside wp-content/uploads. None takes more than a few minutes and all four together close the paths attackers actually use.

How to Protect WordPress Files: Permissions, wp-config, and the Editor You Should Disable

File security in WordPress is unglamorous and mostly consists of removing capabilities nobody needed. The dashboard can edit theme files, so a compromised admin account becomes remote code execution. The uploads directory accepts files, so an upload bug becomes a shell. Neither is exotic; both are closed by configuration you can apply this afternoon.

Table of contents

Permissions: what the numbers should be

The general rule is that WordPress needs to read everything and write to very little.

# directories
find /var/www/html -type d -exec chmod 755 {} \;

# files
find /var/www/html -type f -exec chmod 644 {} \;

# wp-config.php, tighter
chmod 640 /var/www/html/wp-config.php

755 on directories means the owner can write, everyone else can read and traverse. 644 on files means the owner can write, everyone else can read. That is the standard and it is correct for the overwhelming majority of installs.

What should never appear: 777. It means anyone with any access to the machine can modify the file, and on shared hosting anyone includes other customers. Plugins that ask you to chmod 777 a directory to work are asking you to accept a real risk to save them handling an ownership problem properly. The actual fix is nearly always that the web server user does not own the directory.

sudo chown -R www-data:www-data /var/www/html
# on some distributions: apache:apache or nginx:nginx

Get the ownership right and the permissive modes stop being necessary. wp-config.php at 640 rather than 644 removes world-read, which matters on shared hosting where other accounts run under different users on the same filesystem.

Protecting wp-config.php

It contains the database credentials and the authentication salts. It should not be readable over HTTP under any circumstance, and a misconfigured server that serves .php files as plain text turns it into a public credential dump.

On Apache, deny it explicitly in .htaccess:

<Files "wp-config.php">
  Require all denied
</Files>

On nginx, the equivalent location block:

location ~* wp-config\.php { deny all; }
location ~* /\.(git|env|htaccess) { deny all; }
location ~* /wp-content/uploads/.*\.php$ { deny all; }

The other option, which is stronger and less known: move wp-config.php one directory above the web root. WordPress checks the parent directory automatically, so no code change is needed. A file outside the document root cannot be served by the web server at all, regardless of configuration mistakes.

While you are in there, regenerate the salts. If the site has ever been compromised, or the config was ever committed to a repository, the existing salts should be considered public. Replacing them invalidates every existing session, which is exactly what you want after an incident.

Disable the dashboard file editor

By default, an administrator can edit theme and plugin PHP files from Appearance and Plugins in the dashboard. This is a code execution feature reachable through a login form.

Any compromised admin account — reused password, successful phishing, a plugin privilege escalation — becomes the ability to write arbitrary PHP to your server. Turning it off means an attacker who gets admin access still has to find a second vulnerability to get code execution.

// wp-config.php
define('DISALLOW_FILE_EDIT', true);

// stronger: also block plugin and theme installs from the dashboard
define('DISALLOW_FILE_MODS', true);

DISALLOW_FILE_EDIT costs you nothing, because editing production PHP through a browser textarea with no version control and no undo was never a good idea anyway.

DISALLOW_FILE_MODS is stricter — it also blocks installing and updating plugins and themes from the dashboard, which means you need another route for updates. Use it when deployments come from a repository. Do not use it on a site whose owner relies on one-click updates, because the practical result is a site that never gets security patches.

Stop PHP executing in uploads

wp-content/uploads is the one directory that accepts files from users. If an attacker can place a .php file there and the server will execute it, they have a shell. Blocking execution in that directory means an upload bypass produces a useless file instead of a foothold.

On Apache, an .htaccess inside the uploads directory:

<FilesMatch "\.(php|phtml|php3|php4|php5|php7|phps)$">
  Require all denied
</FilesMatch>

On nginx, the location block from earlier does the same job. nginx does not read .htaccess files at all, which is a common source of surprise for people moving from Apache and assuming their hardening came with them.

The same reasoning applies to any directory holding user-supplied content — cache directories, plugin-specific upload paths, temporary directories. The rule is: a directory that accepts writes from the web should not execute code.

Also disable directory listing, so that a missing index file does not turn a directory into a browsable inventory of everything in it. Options -Indexes on Apache; nginx has it off by default unless autoindex on was set.

The rest of the file-level list

  • Delete what you are not using. Deactivated plugins and unused themes are still files on disk and still get exploited. Deactivated does not mean unreachable — several notable vulnerabilities were exploitable in plugins that were installed but switched off.
  • Keep everything updated. The overwhelming majority of WordPress compromises exploit known vulnerabilities in outdated plugins, not novel attacks on core. Update or remove — those are the two options.
  • Remove leftover files. readme.html, license.txt, and installer files from a migration. Minor information disclosure, free to remove.
  • Block access to dotfiles. .git, .env, .htaccess itself. A .git directory served over HTTP hands over your entire source history including anything sensitive ever committed.
  • Serve everything over HTTPS. Credentials sent to wp-login.php over plain HTTP are readable in transit.
  • Use SFTP rather than FTP. Plain FTP sends credentials unencrypted.

The .git one is worth emphasising because it is common and severe. Deploying by running git pull in the web root leaves .git publicly readable unless explicitly blocked, and tools that reconstruct a repository from an exposed .git directory are freely available.

Detecting a change you did not make

Prevention is most of the work, but knowing when something changed is what turns a long compromise into a short one.

  • Checksum core files. wp core verify-checksums compares your core files against the official release and reports any that differ. It is one command and it catches injected code in core immediately.
  • File integrity monitoring. Several security plugins watch for modified files and alert. Noisy during updates, valuable in between.
  • Read the access logs. Repeated POSTs to wp-login.php from one address, or requests for .php files inside uploads, are worth noticing.
  • Watch for new admin users. A backdoor account is a standard follow-up to a compromise, and one that outlives the file you removed.
wp core verify-checksums
wp plugin verify-checksums --all
wp user list --role=administrator

That last command takes a second and is worth running occasionally regardless. An administrator account nobody recognises is not ambiguous.

How this fits the rest of the stack

Everything above assumes you can reach the filesystem to apply it, which on a lot of hosting means an SFTP client, a set of credentials, and a database GUI configured separately. Managed WordPress on RunxBuild puts a file manager in the dashboard — browse, edit, upload, unzip, download — and a database browser beside it, so checking permissions or dropping an .htaccess into the uploads directory is a browser action rather than a toolchain. Plans start at $3 a month. WordPress files on RunxBuild covers the file manager, and the RunxBuild hosting calculator shows the site, storage, and bandwidth as separate figures when you are sizing it.

Useful related references:

FAQ

What file permissions should WordPress use?

755 for directories and 644 for files, with wp-config.php tightened to 640. Never use 777 — it lets any user on the machine modify the file. If a plugin appears to need 777, the real problem is almost always that the web server user does not own the directory.

How do I protect wp-config.php?

Deny HTTP access to it explicitly — a <Files "wp-config.php">Require all denied</Files> block on Apache, or a matching location block on nginx. Better still, move it one directory above the web root; WordPress checks the parent automatically and a file outside the document root cannot be served at all.

Should I disable the WordPress file editor?

Yes. Add define('DISALLOW_FILE_EDIT', true); to wp-config.php. The dashboard editor lets any compromised admin account write arbitrary PHP to your server, and editing production code in a browser textarea with no version control was never a good practice.

How do I stop PHP running in the uploads folder?

Add an .htaccess in wp-content/uploads denying execution of .php files, or a matching nginx location block. Note that nginx does not read .htaccess files at all, so hardening that worked on Apache does not carry over to an nginx migration.

How do I tell if my WordPress files have been modified?

Run wp core verify-checksums and wp plugin verify-checksums --all, which compare your files against the official releases. Also check wp user list --role=administrator for accounts you do not recognise, since a backdoor admin user commonly outlives the malicious file itself.

#how to protect wordpress files#wordpress security#wp-config.php#file permissions#wordpress hardening