Vulnerabilities
wp-config.php.bak vs .env on Production Origins
July 19, 2026
wp-config.php.bak vs .env on production origins is two costumes of live secrets in the document root. /.env holds framework secrets. wp-config.php is supposed to be executed as PHP, not served as text — but editors leave wp-config.php.bak, .save, .old, and wp-config.php~ that many static hosts will GET as plaintext: DB_NAME, DB_PASSWORD, AUTH_KEY. Neither belongs next to index.html. RoastMyOpsec probes /.env and /.env.local with bounded GETs looking for signatures. It does not currently score wp-config.php.bak, does not parse PHP configs, and does not use leaked keys.
The practical difference
A correctly served wp-config.php runs and returns nothing useful to a GET. A backup extension often bypasses PHP and dumps the file. .env is always a static object if the origin serves it. debug.log is a cousin leak. composer.json is inventory, not usually the password — see those guides.
robots.txt Disallow: /wp-config.php.bak advertises the name. Deny at the CDN instead.
How to choose a deny list
CI: fail if .env, wp-config.php.bak, wp-config.php.save, wp-config.php.old, or *~ editor files appear in the artifact. CDN: deny those suffixes even if CI is perfect. Never copy wp-config into a public bucket. Staging hostnames that are guessable get the same rules. Rotate DB passwords if a backup was ever world-readable.
| File | Typical leak | Roast today | Takeaway |
|---|---|---|---|
| /.env | Live secrets | Bounded signature GET | See .git vs .env |
| /wp-config.php.bak | DB and salts as text | Not scored; deny anyway | Same class |
| /wp-config.php (executed) | Should be empty to GET | Not a scored path | Keep PHP execution on |
| /wp-content/debug.log | Error inventory | Not scored | See debug.log vs framework debug |
When wp-config still wins (off the public origin)
The live PHP file on a server that executes it is how WordPress boots. A downloadable backup never wins. Pair with .htaccess vs web.config if the same zip also shipped IIS/Apache config.
What the roast can prove
Signature hits on /.env can surface. wp-config backups are not scored paths. Confirm a deny at the edge. Pair with WordPress XML-RPC if the same host also left an extra auth surface.
Common mistakes
The first mistake is editing wp-config on production over FTP and leaving .bak in place.
The second mistake is allowing .bak because 'PHP would run it' on a host that serves unknown extensions as text/plain.
The third mistake is Disallow: /wp-config.php.bak and calling it access control.
Free audit the URL you own
RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.
Free audit nowFAQ
- Is a public wp-config.php.bak a vulnerability?
- Yes — treat it as a credential leak. Deny the name, delete the file, and rotate secrets if it was reachable.
- Does RoastMyOpsec fetch wp-config backups?
- Not as scored paths today. It does probe .env. Deny backup suffixes at the edge anyway.
- Will the scanner use leaked database passwords?
- No. Bounded GETs and signatures only. No recursive dump, no exploit payload.
Sources
Related guides
Vulnerabilities
Exposed .git vs .env on Production WebsitesVulnerabilities
WordPress debug.log vs Framework Debug on ProductionVulnerabilities
.htaccess vs web.config on a Public Origin