The five things we check first on any website
Before we quote a penetration test, we run a fifteen-minute pass that costs nothing and finds most of what matters. Here is exactly what we look at, in order, and the free tools you can use to run the same checks yourself today.
When someone asks us to look at their site before committing to a full penetration test, we do not start with an exploit. We start with a fifteen-minute pass over five things that, between them, predict most of the trouble a site is in. None of it requires an account or a login — everything below is either public information or something you already own.
Here is that pass, in the order we run it, with a free tool for each check.
1. TLS and security headers
First, is the certificate actually configured correctly, not just present. A padlock in the address bar tells you almost nothing — it is trivial to get a valid certificate for a site that still accepts weak, outdated protocol versions underneath it. We check the TLS configuration itself: which protocol versions are offered, whether old cipher suites are still accepted, and whether the certificate chain is complete.
Then we check the response headers, because they are where a browser is told how to defend the site on your behalf. Strict-Transport-Security tells the browser to refuse plain HTTP forever, closing off downgrade attacks. Content-Security-Policy restricts which scripts are allowed to run, which is the single most effective defense against cross-site scripting. X-Content-Type-Options: nosniff and a sane X-Frame-Options or frame-ancestors close off a handful of older but still-live tricks. Most stacks let you set every one of these in a config file or a single middleware — it is rarely a code change.
# TLS grade and configuration issues
# Run this in a browser instead — it needs to reach your server from outside:
# https://www.ssllabs.com/ssltest/
# Security headers, from the command line
curl -sI https://example.com | grep -iE \
'strict-transport-security|content-security-policy|x-frame-options|x-content-type-options'
# Nothing printed back means none of them are set.SSL Labs' server test is free and does not require an account — it will grade the TLS configuration and list exactly what is weak. For headers, securityheaders.com gives the same kind of graded report if you would rather read a page than a terminal, and our own free website check reads the same headers and certificate back to you in plain English alongside Google's Lighthouse scores.
2. Exposed admin panels and default paths
Every content management system and framework ships with predictable paths — /wp-admin, /admin, /administrator, /.env, /phpmyadmin, a debug console left switched on. None of these need to be discovered; they are guessed, at scale, by scripts that try the same list of forty or fifty paths against every domain they encounter. If one of them resolves to something real and unprotected, that is the whole attack — no cleverness required on the attacker's side.
We are not looking for whether the admin panel exists — most sites need one somewhere. We are looking at what stands between the internet and it: a predictable path, no rate limiting, no second factor, a login never changed from default. A WordPress site with /wp-admin open and no login-attempt limiting is one leaked password list away from a takeover.
for p in wp-admin wp-login.php admin administrator .env \
.git/HEAD phpmyadmin backup.sql .well-known/security.txt; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://example.com/$p")
echo "$p -> $code"
done
# 200 or 301/302 on .env, .git/HEAD or backup.sql: fix today.
# 200 on an admin path: confirm it requires a real login with no default password.If any of those return a 200 you were not expecting, especially .env or .git/HEAD, stop and treat it as urgent — those two hand over database credentials and full source history respectively, and both are read by scanners within hours of going live, not months.
3. Dependency and CMS versions
Every plugin, theme, framework and JavaScript library on your site has a version number, and that version number is usually visible somewhere — a generator meta tag, a script path, a response header. That version number is also a lookup key. There are public databases of exactly which versions of exactly which software have known, published, working exploits.
This is the finding we mentioned in an earlier article: it requires no skill to exploit, because someone else already wrote the exploit and put it on GitHub with instructions. The version number sitting in your page source is an invitation, not a formality.
The practical fix: keep a short list of what you are actually running — CMS core, theme, every plugin, any JavaScript libraries loaded directly — and update on a schedule, not only when something breaks. And if a plugin has not shipped an update in over a year, that is not stable, that is abandoned, and the honest fix is to replace it before it becomes the reason you get called.
4. DNS and email authentication
This has nothing to do with your website's code and everything to do with whether someone can send email that looks like it came from you. Three DNS records decide this: SPF lists the servers allowed to send mail claiming your domain; DKIM cryptographically signs outgoing mail so a receiver can verify it was not altered; DMARC tells receiving servers what to do when a message fails those checks — and gives you visibility into who is trying.
Without DMARC in enforcement mode, anyone can send an email that appears to come from billing@yourcompany.com, and most mail providers will deliver it. This is not a theoretical risk for a small business — invoice fraud built on a spoofed sending domain is one of the most common ways a small company actually loses money, and it costs the attacker nothing to attempt.
dig TXT example.com +short | grep spf
dig TXT _dmarc.example.com +short
# No SPF record: anyone can claim to send mail as you, with nothing to stop it.
# No DMARC record, or a DMARC policy of "p=none": failing mail is still
# delivered — you get no protection, only reporting (if that).A word of caution: do not set DMARC straight to p=reject on a domain that has never had it before. Start at p=none so you get reports on what is currently sending mail as your domain — including services you forgot you connected years ago — fix your SPF and DKIM to cover all of it, and only then move to p=quarantine and eventually p=reject. Skipping straight to reject on a live domain is the single fastest way to lose legitimate invoices and customer replies, and we have seen it done.
5. Backups you have actually tested restoring
This is the check we care most about, because it is the one that determines whether a bad day becomes a bad week or a bad year — and it is the one almost nobody has actually verified. Most small businesses have backups running. Far fewer have ever restored one.
A backup you have not restored is a theory, not a backup. The failure modes repeat: the job has been silently failing for three months and nobody checked the logs. It covers the database but not the uploaded files sitting next to it. It shares host credentials with the live site, so whatever compromised the site also has the backup. Or it exists, restores, and takes eleven hours — a fine number to know in advance, a terrible one to discover while your site is down.
- Does the backup include the database and uploaded files, not just one of them?
- Is at least one copy stored somewhere the live server's own credentials cannot reach or delete?
- Have you restored it — to a throwaway environment, on purpose, in the last three months?
- Do you know, in minutes, how long a full restore actually takes?
- Does anyone besides you know where the backups are and how to trigger a restore?
If you cannot answer all five of those right now, that is not a crisis — it is just the honest starting point. Schedule one test restore this month. It will either confirm you are in better shape than you thought, or it will save you on the day it matters, and there is no third outcome.
What this fifteen minutes buys you
None of these five checks require a penetration test, a contract, or a login we do not already have. That is the point — they are the baseline every site should clear before anyone spends money on deeper testing, and running them costs you nothing but the time to read this list twice: once for your site, once for whoever manages it.
A test finds what is subtle. These five checks find what is already public, already indexed, and already being tried against your site today.
If all five come back clean, that is a good sign — and exactly when a real penetration test starts being worth the money, because it looks past the checklist for mistakes specific to your application, not the generic ones. If something above did not come back clean, fix that first; a test on a site with an exposed .env file mostly just re-tells you the .env file is exposed.

Subin Sunder Raj
Subin leads security and infrastructure at Quantis Sphere. He runs the web and API penetration tests, hardens the Linux and cloud environments client systems run on, and builds the Wazuh SIEM deployments the security practice is built around — the same person scopes the engagement and does the work.