wp-config.php After a Hack: What to Check and What to Rotate

By · Updated · 6 min read

If your WordPress site was hacked, assume everything in wp-config.php is in the attacker's hands: your database credentials, your authentication keys and salts, and any API keys stored there. That means the cleanup isn't finished until you've inspected the file for injected code and rotated the secrets inside it. Skipping the rotation step is one of the most common gaps I find in do-it-yourself cleanups, and it hands the attacker a quiet way back in that has nothing to do with malware files.

wp-config.php is the most sensitive file on a WordPress site. It sits in your site root, and every attacker who gets any kind of foothold reads it first. Here's what they do with it, and what I do about it on every cleanup.

Why attackers go straight for wp-config.php

The file is a treasure map. The database username and password let an attacker connect to your database directly, and once they're in the database they don't need WordPress at all. They can create administrator accounts, inject spam into your posts, or store executable code in the options table. On shared hosting where the database accepts connections from the web server, a stolen database password can outlive every file-level cleanup you do.

The salts are the quieter prize, and most owners have never thought about them. More on those in a moment.

What injected code looks like in the file

Besides reading secrets, attackers like to add code to wp-config.php itself, because it runs on every single page load and nobody ever opens it. When I audit the file, I'm looking for lines that weren't put there by WordPress or the host:

An extra require or include line pulling in a file with a strange path — something in /tmp, a file with a dot-prefixed name, or a path deep inside uploads. A blob of base64 text wrapped in eval(). Anything after the closing comment that says /* That's all, stop editing! */ other than the standard lines that load wp-settings.php. I've also found the whole malicious payload jammed onto line one, before the opening PHP comment block, betting that whoever opens the file will glance at the middle and miss it. Scroll to both ends. Check line one and the last line.

Compare against a stock wp-config-sample.php from the same WordPress version if you're unsure what belongs. The structure is nearly identical; yours just has real values filled in and maybe a few host-specific lines.

The salts problem: forged logins with no password

The eight lines of random characters in wp-config.phpAUTH_KEY, SECURE_AUTH_KEY, and the rest — sign the login cookies WordPress issues. Here's why that matters: anyone who has those values can forge a valid login cookie for any account on your site, including yours, without knowing a single password. No failed login attempts, no password reset emails, nothing in the logs that looks like a break-in. They just show up authenticated.

So after a compromise, the salts must change. Grab eight fresh values from the official WordPress secret-key generator (api.wordpress.org serves them) and replace the old block. The moment you save, every login cookie on the site dies and everyone gets logged out — you, your editors, and the attacker holding a forged cookie. People sometimes think the mass logout means they broke something. It's the opposite. That logout is the entire point.

The rotation list

Rotating one secret and calling it done is wishful thinking. After any real compromise I rotate all of it, in roughly this order:

  1. The salts, for the reason above.
  2. The database password, in your hosting panel, then update wp-config.php to match.
  3. Every WordPress account password, starting with administrators. Delete accounts you can't vouch for.
  4. Application passwords under each user's profile — attackers add these as a low-noise way to keep API access.
  5. Hosting, FTP/SFTP, and cPanel passwords, since a file-level compromise may have exposed them.
  6. Any API keys living in the file or in plugin settings: payment gateways, mail services, backup services.

If the site takes payments or stores customer data, do the database password and admin passwords the same day you discover the hack. Don't wait for the full cleanup to finish.

Protecting the file going forward

A few habits keep wp-config.php from being the easy target next time. Tighten its permissions so it isn't world-readable — 640 works on most hosts, and some run fine at 600. Add a deny rule for it in .htaccess so the web server refuses to hand it out even if PHP ever fails and the server tries to serve it as plain text. It happens; I've watched a host misconfigure PHP and serve config files as downloads for an afternoon.

And here's the one almost everyone gets wrong: delete the leftover copies. wp-config.php.bak, wp-config.old, wp-config.php.save, wp-config.txt — editors and well-meaning developers leave these behind, and attackers request those exact filenames on every site they probe, because a .bak file isn't executed as PHP. It's served as readable text with your database password in it. I check for these on every audit and find them more often than you'd hope.

Two lines worth adding while you're in there

Since you have the file open anyway, two small additions pay for themselves. The first is define('DISALLOW_FILE_EDIT', true); — it removes the theme and plugin code editors from the WordPress dashboard. Those editors are a gift to any attacker who gets an admin session: a built-in tool for writing PHP to your server, no FTP needed. I have never met a site owner who actually used them on purpose, and I've met plenty of attackers who did. Turning them off costs nothing.

The second is making sure debug output is off in production: WP_DEBUG should be false, and if you need logging, keep WP_DEBUG_LOG pointed at a file the public can't fetch. Debug output leaks file paths and occasionally query details, which is exactly the reconnaissance an attacker wants. I find debug mode left on from some long-forgotten troubleshooting session on maybe one site in ten.

You'll sometimes see advice to move wp-config.php one directory above the web root, since WordPress checks there automatically. It works on simple single-site setups and I don't object to it, but it breaks on some managed hosts and complicates some deploy tooling, so I treat it as optional rather than essential. Permissions, the deny rule, and no stray backup copies get you most of the benefit with none of the surprises.

The salts and passwords only stay meaningful if the site itself is actually clean — rotating secrets while a backdoor is still active just means the attacker reads the new ones. If you haven't done the full sweep, start with my guide on finding backdoors, or run the free scan to see where you stand. My guide to security best practices covers the wider hardening picture.

If you'd rather have the whole thing handled — file audit, rotation, backdoor hunt, the works — that's the job my Bulletproof Cleaning exists for. I've read more wp-config files than any person reasonably should, and at this point the weird ones jump out fast.

Common questions

What should I rotate after my WordPress site is hacked?

All of it: the authentication salts in wp-config.php, the database password, every WordPress user password starting with admins, application passwords, your hosting and FTP credentials, and any API keys stored on the site. Attackers who reached your files read wp-config.php first, so treat every secret in it as stolen.

What do the WordPress salts actually do?

The salts sign the login cookies WordPress issues. Anyone holding your salts can forge a valid login cookie for any account without knowing a password, which leaves no failed logins and no trace. Changing the salts invalidates every existing cookie and logs everyone out, including the attacker.

Why did everyone get logged out after I changed my salts?

That's the intended effect, not a bug. Login cookies are signed with the salts, so new salts make every old cookie invalid at once. You and your users just log back in with your passwords. An attacker holding a forged cookie can't, which is exactly why salt rotation belongs in every cleanup.

How can I tell if wp-config.php has malicious code in it?

Look for require or include lines pointing at odd paths, eval wrapped around base64 text, and any code after the 'stop editing' comment besides the standard wp-settings.php lines. Check line one and the very last line, since attackers hide payloads at the extremes. Comparing against wp-config-sample.php from the same version helps.

Is it safe to keep a backup copy of wp-config.php on the server?

No. Files like wp-config.php.bak or wp-config.old aren't executed as PHP, so the server hands them out as plain text containing your database password. Attackers request those exact names on every site they scan. Keep backups off the server, and delete any leftover copies you find in the site root.