A wp-config.php backup is publicly accessible

What it is

A file such as wp-config.php.bak, wp-config.php.old, wp-config.txt or wp-config.php~ is publicly accessible in your WordPress webroot. It most often happens like this:

Why it’s a problem

The key difference from a regular wp-config.php: PHP files are executed by Apache/nginx — they return HTML output, not the code. But a file with a .bak or .txt extension is served by the server as plain text. An attacker opens https://example.com/wp-config.php.bak and gets:

With the keys, the attacker signs the admin’s cookies. With the database, they wipe the content and set a new password. Usually that’s game over.

How to fix it

Step 1 — delete all .bak / .old / .txt backups

cd /var/www/example.cz
ls -la wp-config*
# find and delete
rm wp-config.php.bak wp-config.php.old wp-config.php~ wp-config.txt

Go through the entire webroot too:

find . -type f \( -name "*.bak" -o -name "*.old" -o -name "*~" \) -ls

Step 2 — rotate whatever was in the .bak file

Assume someone has downloaded the file. Replace:

  1. The database password. After changing it, also update wp-config.php: define('DB_PASSWORD', 'newpassword');.
  2. The WordPress security keys (AUTH_KEY etc.). Generate new ones at api.wordpress.org/secret-key/1.1/salt/ and replace them. This change logs out all active users — that’s fine.

Step 3 — block .bak / .old patterns at the web server

So that the next accidentally created backup doesn’t get out:

nginx:

location ~* \.(bak|old|backup|orig|swp|save|~)$ {
    deny all;
    return 404;
}

Apache (.htaccess):

<FilesMatch "\.(bak|old|backup|orig|swp|save|~)$">
    Require all denied
</FilesMatch>

Step 4 — back up properly

A backup of wp-config.php belongs outside the webroot, under version control (a private git repo, an S3 bucket with SSE, dedicated backup hosting). Never right next to the live version.

References