Browsers make transport, framing, script, cookie, and cross-origin decisions from the headers attached to each HTTP response. A page can look normal while its response omits a policy, sends an unsafe value, or relies on an obsolete field that modern browsers ignore.

The public edge is the right observation point because a CDN, reverse proxy, or route-specific application layer can change headers after the origin builds the page. Redirect hops and the final HTTPS document are separate responses, so each header block needs its own interpretation.

Header presence alone is not a pass. HSTS matters only when delivered over HTTPS, a report-only CSP does not enforce restrictions, cookie and cache requirements depend on the response's sensitivity, and permissive CORS can be intentional only for a public credentialless resource. A clean header review reduces browser-policy gaps but does not prove the application itself is free of vulnerabilities.

Steps to audit HTTP security headers:

  1. Select the exact public HTTPS URL and response context for the audit.

    The response context is one specific route and state, such as a public document, signed-in page, API response, static asset, redirect, or error response. Different contexts can legitimately require different policies.

  2. Capture every response header block from a real GET request to the exact public URL.
    $ curl --no-progress-meter --dump-header - --output /dev/null --location https://developer.mozilla.org/en-US/
    HTTP/2 200
    content-type: text/html
    referrer-policy: strict-origin-when-cross-origin
    ##### snipped #####
    x-frame-options: DENY
    x-content-type-options: nosniff
    strict-transport-security: max-age=63072000
    ##### snipped #####
    cache-control: public, max-age=3600
    ##### snipped #####

    The command sends a GET request and discards the body, so the displayed headers belong to the same request method a browser commonly uses. The final block belongs to the final URL; each earlier 3xx block is separate redirect evidence. The MDN URL is a non-sensitive sample for the URL under review.

  3. Assign a keep/fix/escalate decision to each applicable final-response header from its value and response context.

    Strict-Transport-Security needs a positive max-age on the final HTTPS response; includeSubDomains is appropriate only when every affected subdomain supports HTTPS. An enforced Content-Security-Policy should match the page's scripts, frames, and resource origins; Content-Security-Policy-Report-Only collects reports without enforcing restrictions. X-Content-Type-Options: nosniff is expected where accurate MIME types are served, while CSP frame-ancestors is the modern framing control and X-Frame-Options: ALLOW-FROM is obsolete. Session cookies normally need Secure, HttpOnly, and an intentional SameSite value. Sensitive responses may require Cache-Control: no-store, and credentialed CORS must name approved origins rather than *. A keep decision means the value matches the response; fix means an applicable control is missing, weak, or obsolete; escalate means the required policy depends on application behavior or business-approved origins.

  4. Confirm that every applicable header has an evidence-backed decision for the selected response.

    A complete audit has no unclassified applicable header and makes no site-wide claim from a single route. Redirects, signed-in pages, error responses, APIs, and static assets remain separate audit targets when their response policies differ.