← Recipes

阅读中文版本

Audit Missing Security Headers

Scan responses for missing HSTS, CSP, X-Content-Type-Options, and frame protections, then fix them with a middleware.

~30 minsecurityhttphardening

Task

Check production responses for required security headers and apply a consistent middleware.

When to use this

Security review flags absent headers that browsers rely on to mitigate sniffing and framing attacks.

Prerequisites

  • curl for header inspection
  • Access to the web server or framework
  • A list of required headers

Steps

1. Scan the key responses for required headers.

for url in / /login /api/health; do
  echo "== $url"
  curl -sI https://app.example.com$url | grep -iE 'strict-transport|content-security|x-content-type|x-frame|referrer'
done

Expected output: Missing headers are visible per URL, exposing inconsistent coverage.

2. Set them centrally in middleware.

app.use((req, res, next) => {
  res.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
  res.set('X-Content-Type-Options', 'nosniff');
  res.set('X-Frame-Options', 'DENY');
  res.set('Referrer-Policy', 'strict-origin-when-cross-origin');
  next();
});

Expected output: Every response carries the headers consistently instead of only some routes.

Troubleshooting

Problem

CSP breaks inline scripts

Solution

Introduce CSP in report-only mode, collect violations, then enforce with nonces.

Problem

Header duplicated

Solution

Set headers in one layer; the proxy and the app can both add them.

Limitations

  • Headers alone do not fix injection flaws.
  • HSTS preload is hard to undo.
  • CSP requires ongoing maintenance.

What this recipe does

Check production responses for required security headers and apply a consistent middleware.

Security review flags absent headers that browsers rely on to mitigate sniffing and framing attacks.

Prerequisites

  • curl for header inspection
  • Access to the web server or framework
  • A list of required headers

Procedure

  1. Scan the key responses for required headers.
for url in / /login /api/health; do
  echo "== $url"
  curl -sI https://app.example.com$url | grep -iE 'strict-transport|content-security|x-content-type|x-frame|referrer'
done

Expected result: Missing headers are visible per URL, exposing inconsistent coverage.

  1. Set them centrally in middleware.
app.use((req, res, next) => {
  res.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
  res.set('X-Content-Type-Options', 'nosniff');
  res.set('X-Frame-Options', 'DENY');
  res.set('Referrer-Policy', 'strict-origin-when-cross-origin');
  next();
});

Expected result: Every response carries the headers consistently instead of only some routes.

How to confirm it worked

Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows every key response includes the required headers and enforcing CSP no longer produces new violations.

Troubleshooting

CSP breaks inline scripts — Introduce CSP in report-only mode, collect violations, then enforce with nonces.

Header duplicated — Set headers in one layer; the proxy and the app can both add them.

Limitations

  • Headers alone do not fix injection flaws.
  • HSTS preload is hard to undo.
  • CSP requires ongoing maintenance.