Field guide for MSPs & sysadmins
What your client’s web server is exposing right now
A practical checklist for IT shops and freelance sysadmins who inherit other people’s servers and need to know — fast — what’s leaking before someone else finds it. Updated June 2026.
When you take over a client’s hosting, you rarely get the full story. Someone set up that IIS box or that LAMP stack years ago, copied a tutorial, deployed in a hurry, and moved on. The site works, so nobody looked again. Meanwhile automated bots crawl the entire IPv4 internet every day, requesting the same few hundred predictable paths on every host they find. The gap between “it works” and “it’s safe to leave facing the internet” is exactly where these shops get breached — and as the MSP, it lands on you. Here is what to check, why each one matters, and how to close it.
1. Configuration and secret files sitting in the web root
The single most damaging finding, and one of the most common. A .env file, a web.config, a config.php, an .aws/credentials — any of these reachable over the web hands an attacker your database password, API keys and cloud credentials directly. The classic failure is a deploy that copies the whole project folder, dotfiles included, into the document root. Request /.env on the target; if it returns 200 and you see KEY=value lines, that is a full compromise waiting to happen. The fix is to deny dotfiles at the server (Apache <FilesMatch "^\."> deny, nginx location ~ /\\. { deny all; }, IIS request filtering), move secrets outside the web root, and rotate every credential the file contained — assume it was already read.
2. An exposed .git (or .svn) directory
If /.git/config or /.git/HEAD returns content, the entire version-control directory is downloadable. Off-the-shelf tools reconstruct the complete source code from it in seconds — including secrets in old commits and the exact version of every vulnerable file. Never deploy the .git folder to production; if your workflow checks out code on the server, block /.git in the web server config and deploy from a build artifact instead.
3. Server-status, server-info and phpinfo() pages
Apache’s mod_status (/server-status) and mod_info (/server-info) are wonderful for debugging and catastrophic when left public: they leak live requests, client IPs, and your full configuration. A stray phpinfo.php or info.php does the same for the PHP layer — version, paths, modules, sometimes environment secrets. None of these belong on a production host facing the internet. Restrict the status pages to localhost (Require local) and delete any phpinfo file outright.
4. Downloadable backups and database dumps
Bots specifically request /backup.zip, /backup.sql, /database.sqland similar, because admins so often drop a quick backup in the web root “just for a minute.” A single downloadable SQL dump is the whole database — every user record and password hash — in one click. Backups belong in private, access-controlled storage, never under the document root.
5. Admin panels open to the world
WordPress /wp-login.php, /administrator/, and especially /phpmyadmin/are the most-targeted login surfaces on the internet. You can’t always remove them, but you can stop them being a free-for-all: restrict by IP or VPN where feasible, enforce strong passwords and two-factor authentication, and put rate limiting or a WAF rule in front of the login. A public phpMyAdmin in particular should simply not exist on a production box.
6. Missing security headers
These are the cheapest wins in the whole audit — usually a few lines in the server config — and they’re almost always just not set. The ones that matter: Strict-Transport-Security (HSTS) to stop downgrade attacks, Content-Security-Policy as your strongest defence against cross-site scripting, X-Frame-Options against clickjacking, X-Content-Type-Options: nosniff against MIME confusion, and Referrer-Policy to stop URLs leaking to third parties. Add them once at the server level and every site behind it benefits.
7. No HTTPS, or HTTP that doesn’t redirect
In 2026 there is no excuse for plain HTTP — certificates are free via Let’s Encrypt. But a subtler problem is a site that serves HTTPS yet never redirects the HTTP version. A user (or a link) that hits http:// stays on an unencrypted connection where the session can be intercepted. Add a permanent 301 from all HTTP to HTTPS, then turn on HSTS so the browser refuses HTTP next time.
8. Insecure cookies
Session and auth cookies should always carry Secure (only sent over HTTPS), HttpOnly (unreadable by JavaScript, so XSS can’t steal them) and SameSite (defends against cross-site request forgery). Default framework setups frequently omit one or more. Set all three on anything that authenticates a user.
9. Version and technology disclosure
Every banner you advertise — Server: Apache/2.4.29, X-Powered-By: PHP/7.4, X-AspNet-Version— tells an attacker exactly which exploits to try. Worse, an old version number is a flashing sign that the box hasn’t been patched. Suppress the version (ServerTokens Prod, server_tokens off, expose_php = Off) and, more importantly, actually update the software behind it. End-of-life PHP 7.x, old nginx and unpatched IIS are common, and they ship known CVEs.
How to run this whole checklist in fifteen seconds
You can do every check above by hand with curland a list of paths — and for a single host, you should know how. But when you’re managing ten or twenty client domains, doing it manually each month doesn’t scale. Server Guard runs all of these checks automatically: enter a domain and it returns a 0–100 posture score and a prioritised, plain-English list of what it found, with the exact path or header and a concrete fix for each — formatted as a report you can hand straight to a client. It’s free for the score and your top findings, and paid plans add scheduled weekly re-scans and white-label reports across all your client domains.