"How to deliver an HTTP security header audit that clients actually understand"
"Analyzing security headers is easy. Turning it into a report that a non-technical client understands and pays for is another story. Here's the complete process."
Analyzing a site's security headers is the easy part. Five minutes with curl and you're done.
The hard part is turning that output into something a client understands, approves, and pays for.
In this article I'll show you the complete process: from which headers actually matter, to why a synthetic score changes the conversation, to how to package it all into a presentable deliverable.
The problem: the terminal is not a deliverable
Here's what you get with a single command:
curl -sI https://example.com | grep -i "strict-transport\|content-security\|x-frame"
strict-transport-security: max-age=31536000
content-security-policy: default-src 'self'
Technically complete. Practically useless to deliver.
The non-technical client asks three things, in this order:
- Am I at risk? (yes/no, how much)
- What exactly is missing?
- How much does it cost to fix?
A header dump answers none of these. You need structure.
The 15 headers I evaluate, and how much they weigh
Not all headers have the same impact. This is the weight system I use, out of 82 total points:
| Header | Weight | What it prevents |
|---|---|---|
Strict-Transport-Security |
10 | HTTP downgrade, SSL stripping |
Content-Security-Policy |
10 | XSS, third-party script injection |
X-Content-Type-Options |
8 | MIME sniffing |
X-Frame-Options |
8 | Clickjacking |
Cross-Origin-Opener-Policy |
7 | Cross-window attacks |
X-XSS-Protection |
6 | Legacy browser XSS filter |
Referrer-Policy |
6 | Sensitive URL leaks |
Permissions-Policy |
6 | Unauthorized camera/mic access |
Cross-Origin-Resource-Policy |
5 | Resource hotlinking |
Cross-Origin-Embedder-Policy |
5 | Unauthorized embedding |
Expect-CT |
4 | Fraudulent certificates |
X-Permitted-Cross-Domain-Policies |
3 | Legacy cross-domain policy |
X-DNS-Prefetch-Control |
2 | DNS leaks |
X-Download-Options |
2 | Automatic downloads on IE |
X-Powered-By |
−5 | Information disclosure (should be removed) |
Note the last one: X-Powered-By is the only header with a negative weight. If present, it tells attackers which stack and version you're using. It's a gift to anyone looking for known CVEs.
# nginx
server_tokens off;
proxy_hide_header X-Powered-By;
// Express
app.disable('x-powered-by');
// or better, use helmet which does it automatically
app.use(helmet());
Why the synthetic score changes everything
Sum the weights of present headers, divide by 82, convert to a letter:
| Percentage | Grade |
|---|---|
| ≥ 90% | A+ |
| ≥ 80% | A |
| ≥ 70% | B |
| ≥ 60% | C |
| ≥ 50% | D |
| < 50% | F |
It sounds trivial. It's not, for one purely human reason: "your site is a D" opens a conversation, "you're missing Cross-Origin-Embedder-Policy" closes it.
The grade gives the client an immediate reference point — and, more importantly, a goal. Going from D to B is a concrete, measurable, estimatable task. "Add these headers" is not.
A small data point that always surprises people: if you test the big sites, almost none get an A+. GitHub sits around D (59%). Google gets an F. Not because they're insecure — they have multi-layer defenses — but because headers are only one layer. Showing this to a client reassures them and motivates them at the same time: "you can do better than GitHub in an afternoon."
The three priority categories
A report with 9 missing headers all at the same level is a report no one implements. You need to order by impact:
🔴 High priority — weight ≥ 8
HSTS, CSP, X-Content-Type-Options, X-Frame-Options. These block real, frequent attacks. Do them immediately.
🟠 Medium priority — weight 5–7
Cross-Origin family, Referrer-Policy, Permissions-Policy. Important, but require testing: COEP: require-corp can break external resources, and needs verification.
🟡 Low priority — weight < 5
Legacy and finishing headers. Added to reach A+, not to stop an attack.
Grouping this way turns a list of 9 problems into three tasks. A client approves three tasks. Nine, no.
The deliverable: what makes the difference between good and ignored
I've delivered reports in three formats and the response difference is stark.
| Format | What happens |
|---|---|
| Terminal screenshot | Client thanks you and does nothing |
| Markdown / email | Gets read, then lost in the thread |
| PDF with score, charts, and priorities | Gets forwarded to management and approved |
The PDF wins because it's shareable. The person you talk to is almost never the one who controls the budget. A PDF with a visible "D" circle on page one reaches the decision-maker without you having to explain anything.
What I include, in order:
- Large colored score circle at the top — the only thing everyone looks at
- Pie chart present vs missing — immediate overview
- Bars by category (Transport, CSP, Cross-Origin, Privacy…) — shows where the gap is
- Complete table with header, status, current value, and exact fix to copy-paste
- Recommendations grouped by the three priorities
Point 4 is what makes the difference for the dev who receives the report: not "HSTS is missing" but max-age=31536000; includeSubDomains; preload ready to copy.
And if you need to check multiple domains — an agency with 20 clients, an infrastructure with multiple subdomains — you also need a bulk scan with score comparison. Otherwise you spend the afternoon doing the same thing 20 times.
The tool: free and Pro
I built both parts of this workflow.
🆓 Free version — open source
Analysis of 15 headers, score, recommendations. MIT code on GitHub, online demo.
Perfect for checking your own projects.
💎 Pro version — €9
This is the "deliverable" part described above, ready to use:
- Professional PDF report with score circle, pie chart, category bars, and complete table
- CSV export with statistics, category breakdown, and prioritized recommendations
- Bulk Scan of up to 50 domains at once, with graphical score comparison
- Full source code (Node.js + Python), self-hosted, MIT license
- One-time payment, lifetime updates
→ Security Headers Checker Pro — €9
If you do security audits for clients, it pays for itself on the first report delivered.
In summary
The value isn't in the analysis — curl does that. The value is in three things:
- A score that gives a reference point and a goal
- Priorities that reduce 9 problems to 3 approvable tasks
- A shareable format that reaches the budget-holder
The rest is packaging. But it's the packaging that gets paid.
If you have questions about headers or the process, write in the comments. And if the free project is useful to you, a star on GitHub helps a lot. ⭐
Top comments (0)