PRE-LAUNCH SECURITY

Website launch checklist: eight security checks to run before you go live

Eight passive checks to run before a launch and after a migration: why each one matters, how to verify it with a browser, dig, curl or openssl, what a good result looks like and the usual fix.

Concept illustration of a miniature website building on a launch platform, with eight glass tokens in an arc and copper tweezers placing the last one as a mint glow rises on the horizon.
Concept illustration

Launches and migrations tend to break the same few things. The www name still points at the old host. The new certificate covers www but not the bare domain. The security headers lived in the old server's configuration and did not move. The domain renews next month on a card that expired last year. Most of it shows from the outside, without signing in to anything.

This checklist covers that outside view in eight items. Each one explains why it matters, how to check it by hand, what a good result looks like and the usual fix. Run the list against the new setup before you switch DNS, again right after the switch, and whenever hosting, the CDN, DNS or certificates change. The examples use example.com.

Scope of this guide

The free Launch Readiness Snapshot covers these eight areas with passive checks on one public origin. It reads mail records on the exact hostname you enter, does not check DKIM, and tests the HTTP-to-HTTPS redirect only when you enter an http:// address. It is not a pentest.

1. The pre-launch checklist at a glance

Check every public name you serve, usually the bare domain and www, over both http:// and https://. Before the DNS switch, you can test the new server under the real name with curl -sI --resolve example.com:443:203.0.113.10 https://example.com/, using the new server's IP address in place of the example one.

ItemCheck by handGood result
DNS resolutiondig A, AAAA, CNAME, NSEvery name resolves to the new host; no records pointing at retired services
SPF, DMARC, CAAdig TXT, _dmarc, CAAOne SPF record; DMARC with a report address; CAA naming your CAs
TLS certificateopenssl s_clientTrusted chain, all names covered, TLS 1.2 or 1.3, automated renewal with an owner
HTTPS redirectcurl -sI http://…Permanent redirect to HTTPS, one canonical host, HSTS on the HTTPS response
Security headerscurl -sI https://…CSP, frame protection, nosniff, Referrer-Policy, also on error pages
Technology disclosurecurl -sI, page sourceNo versions in Server, no X-Powered-By, software patched
Cache, compression, CDNcurl -sI with Accept-EncodingCompressed HTML, explicit Cache-Control, personal pages never in shared caches
Domain registrationRDAP lookupExpiry months away, auto-renew and transfer lock on, current contacts

The eight rows follow the eight passive checks in the free Launch Readiness Snapshot, which looks at one public origin without an account. The manual steps below go further than a single pass on one origin can: they cover every hostname, both schemes, error pages, DKIM and your registrar settings.

2. DNS resolution: every name points at the new host

Why it matters. A partial move is easy to miss: the bare domain is on the new server while www is still a CNAME to the old platform. Leftover records are a security problem too. The OWASP subdomain takeover cheat sheet explains how a CNAME pointing at a deleted cloud resource can let someone else claim the subdomain, and how a dangling MX record can let an attacker receive mail for it and even obtain certificates through email-based validation.

How to check.

dig +short A example.com
dig +short AAAA example.com
dig +short CNAME www.example.com
dig +short NS example.com

Repeat the queries against a public resolver (dig @1.1.1.1 …) in case your network holds a cached answer, then go through the full zone export from your DNS provider.

What good looks like. Every public name resolves to the host you expect, AAAA records exist only if the host really serves the site over IPv6, at least two name servers answer (the minimum RFC 1034 sets), and every record has a known purpose and owner.

Typical fix. Repoint or delete stale records. When you retire a service, follow the order OWASP recommends: update or remove the DNS record, wait at least one TTL, and only then delete the cloud resource. Before a cutover, lower the TTL early enough that the old, longer TTL has run out by the time you switch, and raise it again once the move is stable.

3. SPF, DMARC and CAA: the records that speak for your domain

Why it matters. Anyone can put your domain in a From line. SPF lists the servers allowed to send mail for it, DKIM signs messages, and DMARC tells receivers what to do when neither SPF nor DKIM passes in alignment with the visible From domain. Gmail, Yahoo and Outlook.com require all three from bulk senders. CAA names the certificate authorities allowed to issue certificates for your names, and public CAs must check it before issuing.

How to check. Query the domain used in your From addresses, usually the registered domain rather than www:

dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short CAA example.com

What good looks like.

  • SPF: exactly one v=spf1 record, within the RFC 7208 limit of 10 DNS-querying terms (nested includes count), ending in ~all or -all, never +all.
  • DMARC: a record such as v=DMARC1; p=none; rua=mailto:dmarc@example.com, so that reports arrive before you tighten the policy. The current standard, RFC 9989 (May 2026), says domains whose users might post to mailing lists should not publish p=reject; those that still want it should first run at least a month at p=none and as long again at quarantine, comparing the reports.
  • DKIM: every service that sends for you signs with your domain. Public keys sit at selector._domainkey.example.com, so you need each selector to look them up; it appears in the s= tag of the DKIM-Signature header on a message the service sent.
  • CAA: a record such as 0 issue "letsencrypt.org" for each CA you use, including the one your CDN uses. Having no CAA record is allowed, and CAA does not stop an authorized CA from mis-issuing.

Typical fix. Merge duplicate SPF records, drop includes for retired services, and start DMARC at p=none with reports. A hard fail is not automatically safer: RFC 9989 warns that with -all, mail can be rejected on the SPF result before DMARC runs, even when an aligned DKIM signature would have passed, and those rejections never show up in DMARC reports. Receivers that find no DMARC record on a subdomain walk up the DNS tree to the parent domain's policy, and a CA uses the closest CAA record at or above the name it is issuing for, as Let's Encrypt's CAA page explains. A missing _dmarc or CAA record on www is therefore not a gap by itself. The SPF and DMARC check guide goes through reading and fixing these records.

4. TLS certificate: valid, matching and renewed by someone

Why it matters. An expired or mismatched certificate stops visitors at a browser warning, and on a host that uses HSTS they cannot click through it. Renewals are also getting more frequent: under CA/Browser Forum Ballot SC081v3, publicly trusted certificates issued since 15 March 2026 are valid for at most 200 days, falling to 100 days from March 2027 and 47 days from March 2029. Let's Encrypt stopped sending expiry emails on 4 June 2025.

How to check. For each hostname:

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -issuer -enddate -ext subjectAltName

Run s_client on its own as well: the output should include Verify return code: 0 (ok) and show the negotiated protocol.

What good looks like. The chain verifies with the intermediates the server sends, the certificate covers every name you serve, the connection uses TLS 1.3 or 1.2, renewal is automated, and the runbook names who owns it. An expiry alert exists that does not rely on the certificate authority.

Typical fix. Automate renewal with ACME. Let's Encrypt recommends ACME Renewal Information (ARI) or renewing about two-thirds of the way through a certificate's lifetime, and warns that a fixed 60-day renewal interval will no longer be enough once certificates last 45 days. After a migration, confirm that the new platform actually renews. One handshake shows only the protocol that was negotiated, so use a scanner that lists every supported version to confirm TLS 1.0 and 1.1 are off.

For how the certificate, HSTS and the browser’s other protections fit together during an HTTPS visit, see the guide to how HTTPS works.

5. HTTPS redirect: one hop to HTTPS, one canonical host, then HSTS

Why it matters. Old links, bookmarks, scripts and older clients still request http:// addresses. A redirect moves them to HTTPS, but, as hstspreload.org points out, an on-path attacker can intercept and rewrite that redirect. HSTS closes the gap for every visit after the first secure one.

How to check.

curl -sI http://example.com/
curl -sI http://www.example.com/
curl -sIL "http://example.com/page?x=1" | grep -iE '^(HTTP|location)'

What good looks like.

  • A permanent redirect (301, or 308 to keep the request method) to the same path on HTTPS on the same host, as MDN's TLS guide advises, then at most one more hop to the canonical host. Path and query string survive.
  • The HTTPS response sends Strict-Transport-Security. Browsers ignore the header over plain HTTP, so the redirect itself does not need it.
  • No mixed content: browsers block scripts loaded over http:// on HTTPS pages.

Typical fix. Redirect in the server or CDN, not in JavaScript. Raise the HSTS max-age in stages up to a long value such as 31536000 (one year), and add includeSubDomains only when every subdomain serves HTTPS. hstspreload.org now recommends HSTS but not preloading. If certificates use the ACME HTTP-01 challenge, keep port 80 reachable. To test this item with the Launch Readiness Snapshot, enter the http:// address; with a bare domain or an https:// address it checks HSTS max-age and mixed content instead.

6. Security headers: check the final response and the error pages

Why it matters. Security headers tell the browser what a page may load, who may frame it and how to treat content types. They often live in a server or CDN configuration, so a hosting move can drop them. They limit the damage of bugs such as cross-site scripting; they do not fix the bugs.

How to check.

curl -sIL https://example.com/
curl -sI https://example.com/no-such-page

Check the error page as well: without the always parameter, nginx sends add_header values only with certain status codes, as the OWASP HTTP Headers Cheat Sheet notes.

What good looks like. A reasonable starting set for a simple site:

Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
Strict-Transport-Security: max-age=31536000
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), camera=(), microphone=()
  • Roll out the CSP as Content-Security-Policy-Report-Only first. It has to allow everything your pages legitimately load, and 'unsafe-inline' defeats much of its purpose.
  • frame-ancestors does not inherit from default-src and is ignored in a <meta> tag; X-Frame-Options: DENY is the older fallback.
  • Session cookies carry Secure, HttpOnly and an explicit SameSite (see MDN on Set-Cookie). HttpOnly stops scripts on the page from reading the cookie (for example through document.cookie), but the browser still sends it with matching requests, so it limits cookie theft through XSS without preventing XSS itself.
  • No X-XSS-Protection header, or set it to 0.

Typical fix. Set headers in one layer (server, application or CDN) so that every response, error pages included, gets each header exactly once. The security headers check guide explains each header in detail.

7. Technology disclosure, caching and compression

Technology disclosure

Why it matters. Server, X-Powered-By and generator tags tell anyone what software you run, and MDN notes that detailed version numbers can make known vulnerabilities easier to find. Hiding them is hygiene, not protection: OWASP's testing guide calls it security through obscurity, and MDN calls patching the more robust approach.

How to check. Run curl -sI https://example.com/ | grep -iE '^(server|x-powered-by):', then search the page source for generator and for script file names that include version numbers.

What good looks like. Server: nginx without a version number, and no X-Powered-By.

Typical fix. server_tokens off; in nginx, expose_php = Off in php.ini, app.disable('x-powered-by') in Express. If a page reveals an outdated library, update it rather than hide it.

Cache, compression and CDN

Why it matters. Caching rules decide who gets a stored copy of a response. A personal page cached by a CDN can be served to the next visitor, which is why MDN says personalized responses need Cache-Control: private.

How to check. Run curl -sI -H 'Accept-Encoding: br, gzip' https://example.com/, then sign in, open an account page and read its response headers in the browser's developer tools.

What good looks like. HTML served with Content-Encoding: br or gzip; an explicit Cache-Control on every response; a long max-age plus immutable only on versioned static files; private or no-store on pages with user data (no-cache still allows storing).

Typical fix. Set Cache-Control per type of route, keep signed-in paths out of the CDN cache, and compress text at the server or CDN. Having no CDN is not a risk in itself; the website performance guide covers speed.

8. Domain registration: expiry, lock and contacts

Why it matters. When a domain under a generic top-level domain such as .com expires, ICANN's Expired Registration Recovery Policy requires the registrar to interrupt its DNS resolution for a period, so the site and email stop working together. Renewal reminders go to the contact on file, which may be a former employee or a mailbox on the expiring domain itself.

How to check. Use ICANN's lookup tool. Since 28 January 2025, RDAP has been the definitive source of registration data for generic top-level domains; WHOIS is still required only for .com, .name and .post. For country-code domains, use the registry's or registrar's own lookup. Then sign in to the registrar account and check its settings.

What good looks like.

  • Expiry months away, auto-renew on, and a payment method that will still be valid on the renewal date.
  • clientTransferProhibited set, plus update and delete locks where the registrar offers them; no clientHold or serverHold, which keep the domain out of DNS.
  • Contacts that reach more than one person, with at least one address that is not on the domain itself, and multi-factor sign-in on the registrar account.

Typical fix. Turn on auto-renew, renew for several years, ask the registrar to set the lock statuses (ICANN's EPP status code guide explains each one) and update the contacts.

9. What this checklist does not cover

These eight items describe the public setup around your site. A site can pass all of them and still be easy to break into, because none of them looks at the application or at how it is run. Review these separately:

  • Application vulnerabilities: injection, cross-site scripting in your templates, unsafe uploads, access between accounts.
  • Authentication and sessions: sign-in, password reset, multi-factor authentication, admin panels.
  • Dependencies and servers: CMS plugins, packages, operating system patches.
  • Secrets and access: keys in repositories or front-end bundles, and who can reach production, the DNS provider and the registrar.
  • Backups: a restore you have actually tested.

The website security audit guide walks through sign-in, permissions and other application-side checks, and the OWASP Web Security Testing Guide gives detailed test cases.

A quick first pass on one origin. The free Launch Readiness Snapshot needs no account. For one public origin, it reads public DNS, mail DNS records, domain registration data, the TLS handshake and the HTTP response of the home page, and sends no exploits, port scans, login attempts or load. You get a score, a hardening grade, counts of risk signals and passed checks, and up to three signals to look at first. It is not a pentest: a good score means these public signals looked healthy at that moment. The Free plan covers security checks only; the six audit areas (security, technical SEO, AI visibility, accessibility, performance, integrations) start at $49/month on the Starter plan.

Common questions

Does passing these eight checks mean my website is secure?

No. They cover the public configuration around the site, not application code, sign-in, dependencies or backups, and a passive check is not a penetration test. A clean result means one layer is in order.

When should I turn on HSTS during a launch?

Once HTTPS works on every hostname you serve, the HTTP redirect is in place and certificate renewal is automated. Start with a short max-age, raise it in steps when nothing breaks, and leave preloading out of the launch: hstspreload.org no longer recommends it, and the security headers check guide explains why.

Does a domain that never sends email need SPF and DMARC?

Yes, because anyone can still put it in a From line. Publish v=spf1 -all and a DMARC record with p=reject. If the domain receives no mail either, add a null MX record (MX 0 .) as defined in RFC 7505; Germany's BSI asks for all three on unused domains.

Why does the Launch Readiness Snapshot not show my HTTP-to-HTTPS redirect?

With a bare domain or an https:// address, it tests the HTTPS site and checks HSTS max-age and mixed content instead. Enter the http:// address to test the redirect. That run skips the TLS check, so run both.

Is WHOIS still the right place to check domain expiry?

For generic top-level domains such as .com or .org, RDAP has been the definitive source since 28 January 2025, and ICANN's lookup tool uses it. For country-code domains, use the registry's or registrar's own lookup.

Sources & further reading

  1. MDN: Transport Layer Security (TLS) configurationdeveloper.mozilla.org
  2. MDN: Strict-Transport-Securitydeveloper.mozilla.org
  3. HSTS Preload List Submissionhstspreload.org
  4. OWASP HTTP Headers Cheat Sheetcheatsheetseries.owasp.org
  5. OWASP Subdomain Takeover Prevention Cheat Sheetcheatsheetseries.owasp.org
  6. RFC 9989: DMARCwww.rfc-editor.org
  7. RFC 8659: DNS Certification Authority Authorization (CAA) Resource Recordwww.rfc-editor.org
  8. CA/Browser Forum Ballot SC081v3: reducing certificate validity periodscabforum.org
  9. Let's Encrypt: Decreasing Certificate Lifetimes to 45 Daysletsencrypt.org
  10. ICANN: Launching RDAP; Sunsetting WHOISwww.icann.org
Sitelemetry team

Prepared by the Sitelemetry editorial team. Explore the linked sources for further detail.

SITELEMETRY

Put what you learned to work.

Explore your website’s structure, settings and signals with Sitelemetry.