Website security checklist
24 items, each with a command to check it yourself.
Every item below can be verified from outside your site in one line, so you never have to take anyone's word for it — including ours. Each one also names the check that watches it automatically, and the last section lists the five controls that matter most and that no external scan can see.
The checkup runs the same reads on every item in the first six groups. It asks for a free account before showing the report, takes no card, and will not scan banks, government sites or the major platforms.
Group 1 of 6
Transport
Whether a visitor reaches you without a browser warning, and whether the connection can be tampered with in between.
Serve the whole site over HTTPS, with a valid certificate
An expired or mismatched certificate is a full-page interstitial. Most visitors do not click through one, and the ones who do learn that your warnings mean nothing.
Check it yourself
echo | openssl s_client -servername yourdomain.com -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -enddateIn the DomainGuard report: HTTPS connection
Redirect every HTTP request to HTTPS
A site that answers on plain HTTP hands the first request to whoever is on the network. Redirecting is one rule and it closes that.
Check it yourself
curl -sI http://yourdomain.com | head -n 1In the DomainGuard report: HTTP to HTTPS redirect
Send an HSTS header with a long max-age
HSTS tells the browser to refuse plain HTTP for this name in future, which removes the redirect as an attack point rather than just using it.
Check it yourself
curl -sI https://yourdomain.com | grep -i strict-transport-securityIn the DomainGuard report: HSTS max-age
Remove mixed content
One script or stylesheet loaded over HTTP on an HTTPS page is a script an attacker on the same network can replace. The padlock stays, and the page is no longer yours.
Check it yourself
Open the page, then look at the browser console for mixed-content warnings.In the DomainGuard report: Mixed content
Group 2 of 6
Security headers
Nine headers, set in one place, that cost nothing and turn several classes of bug into a non-event.
Set a Content-Security-Policy
The one that does the most work. It limits where scripts, styles and frames may come from, which is what stops an injected script from reaching anywhere useful.
Check it yourself
curl -sI https://yourdomain.com | grep -i content-security-policyIn the DomainGuard report: Content-Security-Policy
Set X-Frame-Options, or a CSP frame-ancestors directive
Stops your login or checkout page being loaded inside somebody else's page and clicked through invisibly.
Check it yourself
curl -sI https://yourdomain.com | grep -iE 'x-frame-options|frame-ancestors'In the DomainGuard report: X-Frame-Options
Set X-Content-Type-Options: nosniff
Stops the browser guessing that an uploaded file is really a script. One header, no configuration.
Check it yourself
curl -sI https://yourdomain.com | grep -i x-content-type-optionsIn the DomainGuard report: X-Content-Type-Options
Set a Referrer-Policy and a Permissions-Policy
Referrer-Policy stops your internal URLs leaking to every site you link to. Permissions-Policy turns off camera, microphone and geolocation for anything embedded in your pages.
Check it yourself
curl -sI https://yourdomain.com | grep -iE 'referrer-policy|permissions-policy'In the DomainGuard report: Referrer-Policy
Group 3 of 6
Files that should not be there
The fastest category to turn into an incident, because there is nothing to exploit. The file is simply reachable.
Confirm .env is not served
A .env file holds live database credentials, API keys and mail passwords. It is the single highest-value file on most small business sites.
Check it yourself
curl -s -o /dev/null -w "%{http_code}\n" https://yourdomain.com/.envIn the DomainGuard report: .env files
Confirm the .git folder is not served
An exposed .git directory can be reassembled into your entire source history, including whatever secret was committed once and removed in the next commit.
Check it yourself
curl -s -o /dev/null -w "%{http_code}\n" https://yourdomain.com/.git/HEADIn the DomainGuard report: Git folders
Move backups and database dumps out of the web root
backup.zip and site.sql sitting next to index.php are guessable, and the scanners guessing them are automated.
Check it yourself
curl -s -o /dev/null -w "%{http_code}\n" https://yourdomain.com/backup.zipIn the DomainGuard report: Backups
Turn off debug pages and stack traces in production
A framework debug page prints file paths, environment variables and sometimes credentials to anyone who triggers an error.
Check it yourself
Request a URL that does not exist and read what comes back.In the DomainGuard report: Debug pages
Group 4 of 6
Email authentication
Three DNS records that decide whether your mail is delivered and whether anyone else can send as you.
Publish an SPF record that ends in -all
A record ending in ~all is a soft fail and is widely treated as a shrug. Ending in -all is the one that means something. Watch the 10-DNS-lookup limit while you do it: over it, the result is permerror and everything fails.
Check it yourself
dig +short TXT yourdomain.com | grep spf1In the DomainGuard report: SPF policy strength
Publish DKIM keys for every service that sends mail as you
DKIM survives forwarding where SPF does not, so it is the record that keeps your mail authenticated through mailing lists and forwarding rules.
Check it yourself
Ask each sending vendor for its selector, then: dig +short TXT selector._domainkey.yourdomain.comIn the DomainGuard report: DKIM
Publish a DMARC record, starting at p=none with a reporting address
It changes nothing about delivery and starts a daily feed naming everyone who sends mail as your domain. Without it, you have no way to know.
Check it yourself
dig +short TXT _dmarc.yourdomain.comIn the DomainGuard report: DMARC
Lock down domains that send no mail
Parked domains, old brand names and redirect domains are spoofed precisely because nobody watches them. SPF -all, DMARC p=reject and a null MX close that off in three records.
Check it yourself
dig +short MX yourparkeddomain.comIn the DomainGuard report: MX records
Group 5 of 6
The domain and DNS underneath
The layer that takes the website and the email down together when it fails.
Know the real expiry date, from the registry
The registrar dashboard is a cached view. Since January 2025 the definitive source for generic top-level domain registration data is RDAP.
Check it yourself
curl -s https://rdap.org/domain/yourdomain.com | grep -A2 expirationIn the DomainGuard report: Expiry date
Point the registrant email at a role mailbox two people read
Every ICANN-required expiry notice goes to the registrant address on the registration record. On an old domain that is usually somebody who left.
Check it yourself
Check the registrant contact in your registrar account.In the DomainGuard report: Registrar
Turn on registrar lock and 2FA at the registrar
Control of the registrar account is control of the domain, which is control of your email, which is control of every password reset you own.
Check it yourself
curl -s https://rdap.org/domain/yourdomain.com | grep -i clienttransferprohibitedIn the DomainGuard report: Registrar
Use more than one nameserver, ideally on separate infrastructure
A single nameserver is a single point of failure for the website and the mail at the same time.
Check it yourself
dig +short NS yourdomain.comIn the DomainGuard report: Nameserver redundancy
Check whether your sending IP is on a blacklist
A DNSBL listing is a common reason mail suddenly lands in spam, and you will never find it by looking at your own inbox.
Check it yourself
Run the free checkup, which queries the common DNSBLs for you.In the DomainGuard report: IP blacklists (DNSBL)
Group 6 of 6
What the site gives away
Version numbers and cookie flags. Small, and they decide how you appear in somebody else's target list.
Stop advertising server and framework versions
Nobody scans by hand. Disclosed versions are matched against published vulnerabilities at scale, within days of a release.
Check it yourself
curl -sI https://yourdomain.com | grep -iE '^server:|^x-powered-by:'In the DomainGuard report: Server version exposure
Set Secure, HttpOnly and SameSite on session cookies
A session cookie without HttpOnly can be read by any script that reaches the page. Without Secure it can be sent over plain HTTP. Both are one-line changes.
Check it yourself
curl -sI https://yourdomain.com | grep -i set-cookieIn the DomainGuard report: Cookie Secure
Know which subdomains exist, including the ones you forgot
Publicly trusted certificates must be logged to be trusted, so every subdomain that ever had HTTPS is in the public record. The forgotten staging site is a classic way in, and an attacker already has this list.
Check it yourself
Search a public Certificate Transparency index such as crt.sh for your domain.In the DomainGuard report: Subdomains (Certificate Transparency)
What no scan can see
Five controls that matter more than anything above.
These are listed separately because we cannot check them, and any tool that implies otherwise is selling you a false green tick. They are also, item for item, the highest-value work on this page.
Test a restore, not just a backup
A backup job that reports success and a backup that restores are different claims. Restore one to a scratch environment and open the data. This is the control that decides whether a ransomware incident is a bad week or the end of the business, and no scanner can verify it for you.
Multi-factor authentication on the four accounts that matter
Email, the domain registrar, DNS, and hosting. In that order. Verizon's annual Data Breach Investigations Report has, edition after edition, put stolen credentials and phishing among the most common ways an intrusion starts, and MFA on these four is the cheapest thing on this page.
Patch on a schedule, and prioritize by exploitation
CISA publishes the Known Exploited Vulnerabilities catalog: vulnerabilities with reliable evidence of active exploitation, each with a required action. Anything of yours on that list goes first, before anything with a higher CVSS score that nobody is actually attacking.
Remove access when people leave
Former staff, former contractors, former agencies. Check the CMS, the hosting panel, the registrar, the DNS provider and any shared mailbox. Nothing external can see this, and it is the account that never gets noticed.
Write down who to call
One page: hosting provider and account number, registrar and account, DNS provider, whoever built the site, and your insurer's incident line if you have cyber cover. Written before you need it, stored somewhere that does not depend on the systems that are down.
Questions people actually ask
How long does this checklist take?
The verification commands take about twenty minutes for one domain. Fixing what they turn up is the variable part: security headers and cookie flags are usually a single configuration change, email authentication takes a couple of weeks because you have to find and authenticate every sender, and moving backups out of a web root takes five minutes.
Do I need to be technical to use it?
The commands need a terminal, and most of them are a single line you can paste after swapping in your domain. If that is not you, run the free checkup instead — it performs the same reads and gives you the results in a report you can hand to whoever runs your site.
Which items matter most?
Three, in order. An exposed .env or .git folder, because that is credentials rather than a weakness. Multi-factor authentication on email and the registrar, because those two accounts control everything else. And a restore you have actually tested. Everything else on this page is real, and none of it is as load-bearing as those.
Does the free checkup cover all of this?
It covers everything in the first six groups, because those are all readable from outside without installing anything. It cannot cover the last group (backups, MFA, offboarding, patch cadence), and no external scan can. Those are listed separately here for exactly that reason.
What does it cost to have this watched?
A free account holds unlimited domains and runs the checkup whenever you press scan, keeping every result so the next one is a comparison. Automatic re-checking starts at Starter, $6.99 a month or $69.99 a year for 25 domains, bought through Apple in-app purchase. Free accounts still get dark-web breach checks and an alert when a vulnerability is published for software found on your sites.
Keep reading
Website security monitoring
What an outside-in scan sees, and why KEV beats CVSS for deciding what to fix.
DMARC monitoring
The email authentication group, in full, with a report opened up.
Expiration monitoring
The domain group, in full: the expiry clock and how auto-renew fails.
The free IT checkup
Every check the scan runs, named before you run it.
Password checker
Strength, entropy and a crack-time estimate, worked out in your browser.
All the free tools
Domain checkup, IT checkup, lookalike check, phishing quiz.
