Security-posture scans
How CompleteStatus grades your site's security headers and TLS certificate A+ to F, how to read findings, and how to fix them with copy-paste snippets.
On this page
CompleteStatus's security layer continuously scans your sites and turns the results into a letter grade, A+ through F. Two monitor types produce grades:
- Security headers — fetches the page and grades its HTTP response headers.
- SSL/TLS certificate — inspects the certificate and the negotiated TLS connection.
Both are included on every plan, including Free.
Setting up a security scan
- Go to /monitors/create and pick the Security headers type (or SSL Certificate for TLS).
- Enter the URL to scan (the full
https://URL for headers; the bare hostname for certificates). - Tick the ownership attestation — you may only scan sites you own or are authorized to check.
- Save. The headers scan runs on your chosen interval (daily is typical; the whole-site quick-add at /monitors/site creates it with a daily interval by default).
The onboarding wizard and the whole-site quick-add can create both monitors for you in one click.
How the header grade is calculated
Every scan starts at a score of 100 and subtracts points for each finding, by severity: critical −25, high −15, medium −10, low −5, info −2. The score maps to a grade:
| Score | Grade |
|---|---|
| 100 | A+ |
| 90–99 | A |
| 80–89 | B |
| 70–79 | C |
| 60–69 | D |
| below 60 | F |
An A+ therefore requires a fully hardened header set — even an informational finding like version disclosure or a missing Cross-Origin-Embedder-Policy costs the top grade. Each check below produces at most one finding per scan (several weak cookies are one finding, deducted once).
What the headers scan checks
- Content-Security-Policy — missing is high. A weak policy is medium: it lets inline script run (
'unsafe-inline'without a nonce, hash or'strict-dynamic'), allows'unsafe-eval', loads scripts from a wildcard*or a scheme-only source (https:,http:,ftp:,data:), or defines neitherdefault-srcnorscript-src. If the only weakness is'unsafe-inline'instyle-src, it is low. When a site sends more than one CSP, a weakness only counts if every policy has it, because browsers enforce all of them. - Strict-Transport-Security (HSTS) — missing, or
max-age=0(which switches HSTS off), is high. It is low whenmax-ageis missing or under 180 days, whenincludeSubDomainsis missing, or when the header declarespreloadbut is not preload-eligible (preload needsmax-ageof at least one year, 31536000, plusincludeSubDomains). - X-Content-Type-Options — anything other than
nosniffis medium. - Clickjacking protection — neither
X-Frame-Optionsnor a CSPframe-ancestorsdirective: high. - Referrer-Policy — missing is low;
unsafe-urlis medium. - Permissions-Policy — missing is low.
- Cross-Origin-Opener-Policy / Cross-Origin-Resource-Policy — each missing header is low.
- Cross-Origin-Embedder-Policy — missing is info. Any value clears it, including
unsafe-none, so ifrequire-corporcredentiallesswould break embedded third-party content, sendCross-Origin-Embedder-Policy: unsafe-none. - Cookie flags — cookies set without
Secure,HttpOnlyorSameSiteare medium; a cookie withSameSite=Nonebut noSecuremakes the finding high (browsers reject it). Well-known CSRF cookies that JavaScript has to read (XSRF-TOKEN,csrftoken,_csrf,csrf_token,_xsrf, also behind a__Host-/__Secure-prefix) are not asked forHttpOnly. - Cookie name prefixes — a
__Host-cookie withoutSecure, withoutPath=/or with aDomainattribute, or a__Secure-cookie withoutSecure, is info. - CORS —
Access-Control-Allow-Origin: *combined withAccess-Control-Allow-Credentials: trueis info: browsers refuse that combination, so it has no effect. List the specific trusted origins if cross-origin requests need cookies. - Version disclosure — info. Flagged when the
Serverheader contains a version number, or when any of these headers is present:X-Powered-By,X-AspNet-Version,X-AspNetMvc-Version,X-Powered-CMS,X-Generator,X-Drupal-Cache,X-Drupal-Dynamic-Cache,X-Runtime.
How the TLS certificate grade is calculated
The certificate check uses the same 100-point scale, but some problems are hard failures that force an F regardless of score: an expired certificate, a protocol below TLS 1.2, an RSA key under 2048 bits (EC under 256), or a SHA-1/MD5 signature. Deductions on top of that:
- Invalid trust chain: −40 (high)
- Expires in under 7 days: −30 (high); under 14 days: −15 (medium); under 30 days: −5 (low)
- Hostname not covered by the certificate's SANs/CN: −20 (medium)
- Negotiated TLS 1.2 instead of 1.3: −5 (low)
A certificate check passes only while the chain is valid, the certificate is unexpired, and the grade is C or better.
Reading your results
On the monitor page
Open a headers monitor from /monitors and the Security headers panel shows the grade badge, every finding sorted critical → info, whether each header is Present or Missing, its current value, and the raw response headers CompleteStatus observed.
The security overview
The /security page aggregates all your certificate and headers monitors in one place:
- Grade distribution — how many monitors sit at each grade.
- Average score and worst grade across the fleet.
- 30-day score trend — a chart of your daily average security score.
- Findings inbox — every open finding across all monitors, sorted by severity and filterable by severity (
critical,high,medium,low,info) and by project.
Fixing findings with copy-paste snippets
Every failing header finding ships ready-to-use remediation for four platforms. On the monitor page, expand a finding and use the Fix — copy & paste tabs:
- Pick your platform: nginx, Apache, Caddy or PHP.
- Click the copy button next to the snippet.
- Paste it into your server config (nginx
serverblock, Apache vhost/.htaccesswithmod_headers, Caddyfile, or PHPheader()call) and reload. - Click Check now on the monitor to re-scan immediately instead of waiting for the next interval.
For example, the HSTS fix for nginx is:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
Warning: Test CSP changes carefully. The suggested strict policy (
default-src 'self'; script-src 'self'; …) will block inline scripts and third-party assets your site may rely on. Adapt the allowlist before deploying to production — How to fix your Content-Security-Policy walks through a safe report-only rollout.
Alerts on grade drops
A headers monitor passes only while its grade is B or better. If a deploy or config change drops the grade to C, D or F, the check starts failing; after two consecutive failed checks CompleteStatus opens an incident and notifies every alert channel whose rule includes the down event. When the grade recovers to B or better, the incident resolves and up (recovery) alerts go out.
To wire this up, open the monitor, add an alert rule pointing at a channel, and select the events you want (the rule form also offers grade_drop and cert_expiry event options alongside down, up and anomaly). See Getting started for channel setup.
Note: Grade regressions surface through the normal incident flow — you'll see the exact grade and every new finding in the incident's monitor detail.
Scanning many domains at once
On the Business and Agency plans, the bulk security audit at /audits scans a whole list of domains (up to 50 per scan on Business, 500 on Agency) across four areas — headers, TLS, email authentication and reputation — and produces an overall grade per domain, with CSV export and white-label PDF reports. It's a point-in-time audit tool, separate from continuous monitors.
Related guides
- SSL, DNS and domain-expiry monitors — certificate monitoring in depth.
- Email authentication monitoring — SPF, DKIM and DMARC.
- REST API — read grades programmatically.
- The complete guide to HTTP security headers — every graded header in depth, on the blog.
Ready to try it?
10 monitors, security grading and email-authentication checks on the free tier — commercial use allowed.