DEV Community

Cover image for How to deliver an HTTP security header audit that clients actually understand
Cub4nH1
Cub4nH1

Posted on

How to deliver an HTTP security header audit that clients actually understand

"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"
Enter fullscreen mode Exit fullscreen mode
strict-transport-security: max-age=31536000
content-security-policy: default-src 'self'
Enter fullscreen mode Exit fullscreen mode

Technically complete. Practically useless to deliver.

The non-technical client asks three things, in this order:

  1. Am I at risk? (yes/no, how much)
  2. What exactly is missing?
  3. 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;
Enter fullscreen mode Exit fullscreen mode
// Express
app.disable('x-powered-by');
// or better, use helmet which does it automatically
app.use(helmet());
Enter fullscreen mode Exit fullscreen mode

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:

  1. Large colored score circle at the top — the only thing everyone looks at
  2. Pie chart present vs missing — immediate overview
  3. Bars by category (Transport, CSP, Cross-Origin, Privacy…) — shows where the gap is
  4. Complete table with header, status, current value, and exact fix to copy-paste
  5. 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:

  1. A score that gives a reference point and a goal
  2. Priorities that reduce 9 problems to 3 approvable tasks
  3. 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)