example.com
example.com, the public demonstration domain reserved by IANA, so no private information appears here. Your own report has the same sections for your website, with the fix steps matched to what we found.Score
All 19 checks
Open findings by severity
Serious gaps found. These should be fixed soon. 12 items need attention; 6 checks passed.
About this website
| IP address | 104.20.23.154, 172.66.147.243 |
|---|---|
| Network | CLOUDFLARENET - Cloudflare, Inc. (AS13335) |
| Behind a protection network | Cloudflare: the address above is the network's, not your own server's |
| Server software | cloudflare |
| Home page | answers with status 200 |
| Page title | Example Domain |
| HTTPS certificate | issued by SSL Corporation on 2026-09-26, expires 2026-12-25 (45 days left) |
| Domain created | 1995-08-14 (31.2 years ago) |
| Domain expires | 2027-08-13 |
| Registrar | RESERVED-Internet Assigned Numbers Authority |
| Name servers | elliott.ns.cloudflare.com, hera.ns.cloudflare.com |
Public information only: DNS, the certificate the site presents, RIPEstat for the network and place, and RDAP for the domain registration.
Fix these first
- high Strict-Transport-Security is sent on every HTTPS response (HDR-001 · Cloudflare or web server)
- high A Content-Security-Policy limits where scripts and other resources load from (HDR-002 · Cloudflare or application)
- high Only TLS 1.2 and TLS 1.3 are accepted (TLS-001 · Cloudflare and web server)
- high Plain HTTP redirects to HTTPS, with no mixed content (TLS-004 · Cloudflare)
- medium At least two nameservers on independent infrastructure answer for the domain (DNS-004 · DNS provider)
- medium Pages cannot be framed by other sites (clickjacking protection) (HDR-003 · Cloudflare or web server)
This site sits behind Cloudflare. 8 of the 12 open findings can be fixed there, and 3 more can be helped by it.
Results by area
Findings and how to fix them
Strict-Transport-Security is sent on every HTTPS response
Why it matters
HSTS tells the browser to use HTTPS only for the site, which closes the window in which a first HTTP request could be intercepted and blocks click-through on certificate errors.
How to fix it
Strict-Transport-Security: max-age=31536000; includeSubDomains. Start with a short max-age (for example 300) for a day, confirm nothing breaks, then raise it. Add always in nginx so it is also sent on error responses.
How to check it yourself
curl -sI https://example.com/ | grep -i strict-transport-security
What a pass looks like
The header is present with max-age of at least 15552000 (180 days); one year (31536000) is the usual target. includeSubDomains is present once every subdomain serves HTTPS.
Risk and how to undo it
Browsers cache the policy; if HTTPS breaks later, visitors cannot bypass it until max-age ends. Do not add preload until you accept that removal from the preload list takes months.
A Content-Security-Policy limits where scripts and other resources load from
Why it matters
CSP is the strongest browser-side defence against cross-site scripting: even if an attacker injects markup, the browser refuses to run scripts the policy does not allow.
How to fix it
Deploy first as Content-Security-Policy-Report-Only with a report endpoint, fix what the reports show, then enforce. Example starting point: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'.
How to check it yourself
curl -sI https://example.com/ | grep -i content-security-policy
Then read the policy for script-src containing 'unsafe-inline', 'unsafe-eval', bare *, or data:.
What a pass looks like
A policy is present. script-src uses nonces or hashes (not 'unsafe-inline'), object-src 'none', base-uri 'self', and frame-ancestors is set.
Risk and how to undo it
An enforced policy that is too tight breaks pages (third-party widgets, analytics, inline handlers). Report-only mode first is the rollback-free path.
Only TLS 1.2 and TLS 1.3 are accepted
Why it matters
TLS 1.0 and 1.1 were formally deprecated in 2021 because their handshake and cipher designs can no longer be made safe. A server that still accepts them lets an attacker on the network push a client down to the weak protocol where one is supported.
How to fix it
nginx: ssl_protocols TLSv1.2 TLSv1.3;. Apache: SSLProtocol -all +TLSv1.2 +TLSv1.3. Reload the service and re-run the test. If the site sits behind Cloudflare, also set the zone's minimum TLS version to 1.2 (SSL/TLS, Edge Certificates); the edge, not your server, then answers the handshake.
How to check it yourself
openssl s_client -connect example.com:443 -servername example.com -tls1_1 </dev/null 2>&1 | grep -E 'Protocol|alert|handshake failure' openssl s_client -connect example.com:443 -servername example.com -tls1_2 </dev/null 2>&1 | grep Protocol openssl s_client -connect example.com:443 -servername example.com -tls1_3 </dev/null 2>&1 | grep Protocol
Some OpenSSL builds refuse to offer 1.0/1.1 at all; in that case use nmap --script ssl-enum-ciphers -p 443 example.com.
What a pass looks like
TLS 1.0 and 1.1 handshakes fail. TLS 1.2 succeeds. TLS 1.3 succeeds (or is simply not offered on very old stacks, which is a medium finding).
Risk and how to undo it
Very old clients (Windows XP, Android 4, old embedded devices) stop connecting. Check access logs for the TLS version in use before the change if clients matter. Rollback: restore the previous directive and reload.
Plain HTTP redirects to HTTPS, with no mixed content
Why it matters
If port 80 serves content, or redirects through an unencrypted hop to a different host, a network attacker can intercept the first request. Mixed content (an HTTPS page loading scripts or images over HTTP) lets an attacker alter the page.
How to fix it
Add a port-80 server block that returns 301 https://$host$request_uri. Change hard-coded http:// URLs in templates and the database to https:// or protocol-relative paths. Then add HSTS (HDR-001).
How to check it yourself
curl -sI http://example.com/ | head -n 5 curl -sIL http://example.com/some/path | grep -iE '^(HTTP|location)' curl -s https://example.com/ | grep -oE '(src|href)="http://[^"]+' | head
What a pass looks like
Port 80 answers with a single permanent redirect (301 or 308) to the HTTPS version of the same host and path. The page source contains no http:// sub-resources.
Risk and how to undo it
Do not redirect to HTTPS before the certificate is valid on every hostname. Rollback: remove the redirect block.
At least two nameservers on independent infrastructure answer for the domain
Why it matters
If the only server that can answer for your zone goes down, every name under the domain stops resolving. RFC 2182 advises placing secondary servers in different networks and places so one outage cannot silence the zone. Two servers in the same rack, or under one account with one provider, share the same failure.
How to fix it
Delegate to at least two servers on separate networks. For important domains add a second DNS provider and keep both in sync through zone transfer from a hidden primary or the providers' APIs. Update the nameserver list at the registrar so it matches the zone.
How to check it yourself
dig +short NS example.com for ns in $(dig +short NS example.com); do echo "== $ns"; dig +short A "$ns" dig +norecurse +short SOA example.com @"$ns" done
Every listed server should answer with the same SOA serial. Then run whois on each server address and compare the network owners to see whether they are really different.
What a pass looks like
At least two nameservers are delegated, each answers authoritatively with the same serial, and they sit on different networks. A single managed DNS provider with its own geographically spread network is a reasonable result if the dependency is documented; two servers of one small host are a finding.
Risk and how to undo it
Two providers can disagree if a record is changed in only one, which gives intermittent wrong answers; automate the sync and compare both after every change. DNSSEC with two providers needs extra care. Rollback: remove the added server from the registrar delegation first, then from the zone.
Pages cannot be framed by other sites (clickjacking protection)
Why it matters
If another site can place your page in an invisible frame, it can trick visitors into clicking buttons they cannot see. The frame-ancestors directive controls who may frame the page.
How to fix it
Add frame-ancestors 'self' to the CSP and X-Frame-Options: SAMEORIGIN. If the site is meant to be embedded, list the exact embedding origins instead.
How to check it yourself
curl -sI https://example.com/ | grep -iE 'content-security-policy|x-frame-options'
What a pass looks like
frame-ancestors 'none' or 'self' (or an explicit allow-list) is present in the CSP. X-Frame-Options: DENY or SAMEORIGIN is sent as a fallback for very old browsers.
Risk and how to undo it
Setting 'none' breaks legitimate embedding (for example inside your own admin or a partner's portal). Check for known embedders first.
X-Content-Type-Options: nosniff is sent
Why it matters
Without it, a browser may guess a file's type from its content and run an uploaded text or image file as a script. The header makes the browser trust the declared type.
How to fix it
add_header X-Content-Type-Options nosniff always; (nginx) or Header always set X-Content-Type-Options nosniff (Apache). Make sure every resource is served with the correct Content-Type.
How to check it yourself
curl -sI https://example.com/ | grep -i x-content-type-options
What a pass looks like
The header is present with the exact value nosniff on HTML, script and stylesheet responses.
Risk and how to undo it
Resources served with a wrong type (for example a script sent as text/plain) stop working. Fix the type rather than removing the header.
DNSSEC is enabled where the registrar and DNS host support it, and validates
Why it matters
DNSSEC lets a validating resolver check that an answer was signed by the zone's owner, which protects against forged or tampered DNS responses. It only works end to end when the zone is signed and the parent zone holds a matching DS record. A half-finished setup is worse than none: a DS record that does not match the signing keys makes validating resolvers return errors, and the domain appears to be down for a large share of users.
How to fix it
Enable signing at the DNS host, then copy the DS data it shows into the registrar's DNSSEC settings. Prefer a host that rolls keys automatically (operational practices are in RFC 6781). Before moving DNS to another provider, plan the DS record: remove it, wait for its TTL to pass, and add a new one only after the new provider signs the zone.
How to check it yourself
dig +short DS example.com dig +short DNSKEY example.com dig +noall +comments example.com A @1.1.1.1 | grep -E 'flags|status' dig +cd +noall +comments example.com A @1.1.1.1 | grep status
A signed domain has DS and DNSKEY records, and the validating resolver's reply carries the ad flag. If the normal query returns SERVFAIL but the +cd query (validation switched off) returns NOERROR, the DNSSEC chain is broken.
What a pass looks like
Either the zone is signed, the DS at the parent matches a published key, and validation succeeds, or there is no DS at all and the lack of DNSSEC is a recorded decision because the registrar or DNS host does not support it. A DS with no matching signed zone is a failure.
Risk and how to undo it
Mistakes take the domain offline for validating resolvers, so change DS records only with the key material in hand and re-run the test right after. Rollback: delete the DS record at the registrar; the zone then resolves unsigned once cached DS answers expire.
Cipher suites are modern and give forward secrecy
Why it matters
Forward secrecy means that recorded traffic cannot be decrypted later if the server's private key leaks. Suites with RC4, 3DES, export-grade keys, NULL encryption or static RSA key exchange do not meet current guidance.
How to fix it
Prefer a maintained generator for the server and OpenSSL version in use rather than hand-written lists, and re-generate when the server software is upgraded. Keep the list short; do not re-enable legacy suites to please one old client.
How to check it yourself
nmap --script ssl-enum-ciphers -p 443 example.com
Look for any suite rated below grade A, any suite using RC4, 3DES, NULL, EXPORT or anonymous (anon) key exchange, and any TLS 1.2 suite that does not begin with ECDHE or DHE.
What a pass looks like
Every offered TLS 1.2 suite uses ECDHE (or DHE with at least 2048-bit parameters) and an AEAD cipher (AES-GCM or ChaCha20-Poly1305). TLS 1.3 suites are used as offered by the library.
Risk and how to undo it
Removing suites can lock out old clients. Test with the oldest client you must support. Rollback: restore the previous cipher directive.
Referrer-Policy limits what URLs leak to other sites
Why it matters
The browser sends the previous page's address to the next site. URLs often contain tokens, search terms or account identifiers that should not leave your origin.
How to fix it
Referrer-Policy: strict-origin-when-cross-origin as the general choice; no-referrer for sensitive areas such as account and billing pages.
How to check it yourself
curl -sI https://example.com/ | grep -i referrer-policy
What a pass looks like
A policy is present and is strict-origin-when-cross-origin, same-origin, or no-referrer. unsafe-url and no-referrer-when-downgrade fail.
Risk and how to undo it
Some analytics and affiliate tools rely on full referrers; check reports after the change.
Permissions-Policy switches off browser features the site does not use
Why it matters
If your site does not need the camera, microphone, geolocation or payment APIs, an injected script or an embedded third party should not be able to request them either.
How to fix it
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(). Allow a feature only for self or a named origin if the site really uses it.
How to check it yourself
curl -sI https://example.com/ | grep -i permissions-policy
What a pass looks like
A policy is present and disables the features the site does not use, for example camera=(), microphone=(), geolocation=().
Risk and how to undo it
Disabling a feature the site does use (video calls, maps, payment buttons) breaks it. List the features in use before choosing the policy.
DNS CAA records restrict which authorities may issue certificates
Why it matters
A CAA record tells certificate authorities that only the listed ones may issue for the domain. It does not stop a determined attacker, but it blocks accidental or opportunistic mis-issuance and gives a clear audit trail.
How to fix it
Add for example example.com. CAA 0 issue "letsencrypt.org" (replace with the CA you use). If you use several CAs list each one.
How to check it yourself
dig +short CAA example.com dig +short CAA www.example.com
What a pass looks like
At least one CAA issue record exists for the apex and names only the authority actually in use. An iodef record with a monitored mailbox is a bonus.
Risk and how to undo it
A CAA record for the wrong CA will make the next renewal fail. Add the record for the current CA first, and test a renewal in a staging window.
Checks to do by hand or that were inconclusive
The scanner could not judge these from the outside. They are not failures.
Certificate renewal is automatic and monitored
Why it matters
Most certificate outages come from a renewal job that silently stopped, not from a hard attack. Automation using ACME removes the human step; monitoring catches the day automation breaks.
How to fix it
Enable the ACME client's timer or cron job, and add an expiry check from outside the server (a monitor that connects over TLS and reads the notAfter date).
How to check it yourself
systemctl list-timers | grep -iE 'certbot|acme' certbot certificates 2>/dev/null crontab -l 2>/dev/null | grep -iE 'certbot|acme' certbot renew --dry-run
Use the equivalent for the ACME client in use (acme.sh, Caddy, Traefik, lego).
What a pass looks like
A scheduled renewal exists, a dry run succeeds, and an external check alerts when any certificate has fewer than 14 days left.
Risk and how to undo it
Renewal hooks that reload the web server must be tested; a failing hook leaves a renewed certificate unused. Keep the old certificate path in place until a reload is confirmed.
Everything that passed (6)
| Check | Area | Severity |
|---|---|---|
DNS-009 Public DNS does not expose internal hostnames or private addresses | DNS | low |
HDR-007 Session and authentication cookies carry Secure, HttpOnly and SameSite | Browser security headers | high |
HDR-008 Responses with private data are not cached by browsers or shared caches | Browser security headers | medium |
HDR-009 Server and framework version banners are not exposed | Browser security headers | low |
HDR-010 CORS allows only named origins and never combines a wildcard with credentials | Browser security headers | high |
TLS-002 Certificate is valid, complete, matches the name, and is not close to expiry | Encryption and certificate | high |
Not covered yet
How to read this report
A fail is a clear gap we observed. A warning is weaker or partial. A pass met the test. The score starts at 100 and drops by more for serious findings. A finding can be wrong, and a clean result is not proof of safety, so confirm each one with the check-it-yourself step before changing anything. Make a backup before changes to a live server. This report is general information and is not legal, privacy or compliance advice.
This is a passive, outside-in scan of public information. It never logs in, never tries to break in and never changes anything on your website.