Safeguard
Developer Tools•

How do you check a site's security headers with curl?

Check security headers from the command line with curl: fetch only headers, filter for the ones that matter, test redirects, and avoid the common traps.

Safeguard Security Team
4 min read

Run curl -sI https://your-site.example/ to print the response headers, then look for Strict-Transport-Security, Content-Security-Policy, X-Content-Type-Options and a frame control. Test the final URL after redirects, not just the first hop, and check static files, error pages and login responses as well as the home page.

Step 1: fetch headers only

curl -sI https://example.com/

The -I flag sends a HEAD request and prints headers. The -s flag hides the progress meter. Some servers answer HEAD differently from GET, so confirm with a GET that discards the body:

curl -s -D - -o /dev/null https://example.com/

Step 2: follow redirects and check every hop

curl -sIL https://example.com/ | grep -i -E "^(HTTP|location|strict-transport|content-security|x-content-type|x-frame|referrer-policy|permissions-policy|cross-origin)"

The -L flag follows redirects. The output shows each response, so you can see the HTTP to HTTPS redirect and the final page. MDN is specific about one point: the redirect from HTTP must not carry the Strict-Transport-Security header, which belongs on the HTTPS response.

Step 3: know what to expect

HeaderWhat good looks like
Strict-Transport-SecurityPresent on HTTPS responses, max-age set deliberately
Content-Security-PolicyPresent, with object-src and base-uri set, no broad unsafe-inline
X-Content-Type-Optionsnosniff
frame-ancestors in CSP'none' or a short list, unless embedding is intended
Referrer-PolicySet explicitly
Set-CookieSecure and HttpOnly, with SameSite chosen on purpose

Step 4: test where headers differ

Headers set on the application often do not reach static files, error pages or redirects served by a proxy or CDN. Test each:

  1. The home page and a deep page.
  2. A static asset such as a script or image.
  3. A 404 page and a redirect.
  4. A login response, to inspect Set-Cookie.
  5. An API route.
curl -sI https://example.com/assets/app.js
curl -sI https://example.com/does-not-exist
curl -si -X POST https://example.com/login -d "u=test&p=test" | grep -i set-cookie

Common traps

  • An nginx add_header directive can silently drop parent headers, and error responses may skip headers without the right flag. See nginx add_header inheritance.
  • A header can appear twice if both the app and the proxy add it. For COEP, MDN says duplicate values are treated as unsafe-none.
  • A header that works in curl may be ignored by browsers for context reasons, for example HSTS sent over plain HTTP.
  • Browser only behaviour such as CSP enforcement needs a real browser test, since curl never runs the page.

Turn it into a regression check

Put the grep lines into a CI job that fails when an expected header disappears. Keep the expected values in a file and diff against it. This catches the common case of a proxy change quietly removing protections.

Try it yourself

Run the web app scan demo and see how findings are grouped, then compare them with what your own curl checks surface.

Click through it at your own pace, or open it full screen.

Quick check

Why does curl show different headers than my browser?

The browser may follow redirects, send cookies and request different paths. Match the URL, method and cookies you are testing.

Does a present header mean the policy works?

No. A weak value is still present. Read the values, then test behaviour in a browser.

Safeguard's policies and gates can run checks in pull requests, and its dependency scan is free to try at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.