A Config File in the Web Root Is Public
I still remember the 3:00 AM page from five years ago—the kind that makes your stomach drop before you even open your laptop. I wasn’t fighting off a sophisticated state-sponsored cyberattack; I was staring at a client’s site that had been gutted because a single `wp-config.php` file was left with permissions so loose a toddler could have read the database credentials. People spend thousands on fancy enterprise firewalls and “next-gen” security suites, yet they completely neglect the basics of securing configuration files. It’s a massive waste of money when the real vulnerability is often just a misconfigured file permission sitting in a public directory.
I’m not here to sell you on complex, expensive security theater that adds latency to your site. Instead, I’m going to show you how to handle the boring, fundamental stuff that actually keeps the lights on. We are going to walk through the practical steps of securing configuration files by locking down permissions, moving sensitive data out of the web root, and ensuring your environment is actually built to last. No fluff, no hype—just the direct methods I use to make sure I don’t get paged in the middle of the night.
Preventing Credential Leakage Before the Breach

The easiest way to stop a leak is to stop putting secrets in your code in the first place. I’ve seen too many developers hardcode database passwords directly into a `wp-config.php` or a `.env` file and then accidentally commit that entire directory to a public GitHub repo. It’s a rookie mistake, but it happens every single day. You need to move toward proper environment variable management. Instead of having a file sitting on the disk that any process (or any intruder) can read, your application should pull its credentials from the system environment. It’s a small shift in how you deploy, but it makes a massive difference in how much surface area you’re exposing.
If you are managing more than one server, you really shouldn’t be manually shuffling files around. This is where secrets management best practices come into play. Using a dedicated tool to inject credentials at runtime means there is no “master file” sitting in a folder waiting to be found. If you aren’t ready for a full vault system, at the very least, tighten your file system access control. If that config file isn’t set to `600` or `640` permissions, you’re basically leaving the keys in the front door.
Mastering File System Access Control Basics

If you’ve ever logged into a server only to find that your `wp-config.php` or a `.env` file is world-readable, you know the panic that sets in. Most people think they need a high-end firewall to stay safe, but they forget that file system access control is your first line of defense. I’ve seen too many setups where the web server user has more permissions than it actually needs. You should be following the principle of least privilege: your web server needs to read the config, not rewrite it. If your permissions are set to `777` because “it just wasn’t working,” you aren’t just fixing a bug; you’re handing out keys to the kingdom.
Once you’ve tightened the permissions, you need to think about where those secrets actually live. Relying solely on flat files is a recipe for disaster, especially when you start scaling. This is where secrets management best practices come into play. Instead of hardcoding everything into a file that might accidentally get caught in a Git commit, you should be looking toward environment variable management. It keeps the sensitive stuff out of the file system entirely, making it much harder for a single directory traversal vulnerability to turn into a total catastrophe.
Five ways to stop your config files from becoming an open book
- Move your sensitive files out of the web root. If your config file lives in the same folder as your public images, you’re playing a dangerous game of chance. Move it one level up so there is no way for a browser to even attempt to request it.
- Use environment variables instead of hardcoding secrets. Storing your database password directly in a `.php` or `.env` file is a recipe for disaster. Push those credentials into the server’s environment so they aren’t sitting in a plain-text file waiting to be scraped.
- Audit your `.htaccess` and Nginx rules. I’ve seen too many people forget to explicitly deny access to dotfiles. If you haven’t specifically told your server to block requests for `.env` or `.git` folders, assume someone is already trying to download them.
- Stop committing secrets to Git. This is a big one. I’ve seen entire hosting setups compromised because a developer pushed a config file to a public repo. Use a `.gitignore` file religiously and treat your credentials like they’re radioactive.
- Set strict permissions and check them often. It’s not enough to set a file to 644 and forget about it. Ensure your web server user owns the files it needs to read, but nothing more. If a file doesn’t need to be writable by the web user, make it read-only. Period.
The bottom line on config security
Stop treating your config files like public documents; if a script can read it, your users shouldn’t be able to.
Permissions aren’t a “set and forget” task—check them regularly, because one sloppy update can undo all your hard work.
Automate your secret management so you aren’t tempted to hardcode passwords just to get a site back online during an outage.
Stop playing roulette with your credentials

At the end of the day, securing your configuration files isn’t about building a digital fortress against state-sponsored hackers; it’s about basic hygiene. We’ve talked about moving secrets out of your codebase, tightening up your filesystem permissions, and ensuring that a single misplaced `.env` file doesn’t hand over the keys to your entire kingdom. If you do nothing else, audit your directory permissions and make sure your sensitive files aren’t reachable via a simple browser request. Most outages and breaches I deal with aren’t caused by sophisticated zero-day exploits, but by preventable mistakes that could have been caught with a simple checklist.
I know it’s tempting to skip these steps when you’re racing to push a new feature or get a site live, but I’ve seen too many people spend weeks rebuilding a business after a single leaked database password. Don’t be that person. Treat your configuration files with the same respect you’d give your physical office keys. It might feel like overkill right now, but when you’re woken up at 3:00 AM by a server alert, you’ll be glad you took the time to do the boring, necessary work. Build it right the first time so you can actually sleep through the night.
Frequently Asked Questions
If I move my config files outside the web root, how do I make sure my application can still actually read them?
That’s the million-dollar question. If you move `wp-config.php` or a `.env` file up one level, you’re essentially playing a game of permissions. The web server user—usually `www-data` or `apache`—needs to be the owner or part of a group that has read access to that specific file. I usually just set the file ownership to the web user and lock it down to `640` or `600`. If the app can’t see it, your site is dead.
What happens to my site if I get too aggressive with file permissions and accidentally lock out the web server user?
You’ll get a “403 Forbidden” error and a very frantic email from your client. Essentially, the web server (usually `www-data` or `apache`) tries to read your files to serve them to the internet, finds the door locked, and gives up. If you get too aggressive with permissions on your core directories, you’ll break your site’s ability to load images, scripts, or even the index file itself. It’s a quick way to turn a functioning site into a white screen of death.
Is it actually worth the headache of using an environment variable manager, or should I just stick to a simple .env file and hope for the best?
Look, if you’re running a single site on a single VPS, a `.env` file is fine—as long as you actually know how to lock down your directory permissions. But if you’re scaling or moving toward containers, sticking to simple files becomes a liability. Managing secrets manually across multiple environments is how things get leaked. An environment variable manager isn’t just “extra work”; it’s the difference between a controlled deployment and a midnight page because a secret ended up in a Git repo.