Security headers are small lines with large names. That makes them attractive launch work: easy to paste, easy to score, easy to misunderstand.

A missing header is not proof that a site is compromised. A present header is not proof that it is safe. Each one asks the browser to enforce a particular boundary, and the value must fit the product.

The goal is not a perfect scanner grade. The goal is a browser that refuses actions your product does not need.

Inspect the real response first

Open the production URL and inspect its response headers. Check the final HTML document, not only an asset or API response. Repeat the request on an authenticated page, an error page, and any important subdomain.

Record which layer adds each value: application, framework, reverse proxy, hosting platform, or CDN. Duplicate policies from several layers can combine in surprising ways. A header configured in source but absent from the public response does not protect anybody.

The OWASP Secure Headers Project is a maintained starting point for understanding the controls. Use it as guidance, then test the policy against your own routes and integrations.

HTTPS comes before HSTS

Redirect every ordinary HTTP request to the intended HTTPS origin. Fix mixed content and certificate errors. Confirm that every subdomain covered by the planned policy can remain on HTTPS.

Only then consider Strict-Transport-Security (HSTS). It tells a supporting browser to use HTTPS for future requests during the declared period. includeSubDomains extends that promise. Preloading makes the commitment broader and harder to reverse.

Do not copy a long lifetime, includeSubDomains, and preload into a young domain because a generator recommended it. First use a short, deliberate rollout and inventory the subdomains. A forgotten HTTP-only service can become unreachable to returning browsers once it is covered.

HSTS is useful because it remembers the secure transport rule. That memory is also why deployment requires care.

Prevent MIME guessing

For responses with a body, send an accurate Content-Type. For HTML, include a safe character encoding where appropriate. Then add:

X-Content-Type-Options: nosniff

This tells browsers not to reinterpret content as a different executable type. MDN’s HTTP header reference describes nosniff as disabling MIME sniffing and requiring the declared type.

The header does not repair incorrect types. Test scripts, styles, uploads, generated files, and error responses after enabling it. Fix the server when a legitimate asset is mislabeled.

Decide who may frame the product

If the application does not need to appear inside another site, restrict framing. The modern control is the frame-ancestors directive in Content Security Policy:

Content-Security-Policy: frame-ancestors 'none'

Use 'self' or an explicit allowlist when your own product or a trusted partner must embed the page. MDN explains how frame-ancestors checks every ancestor in a nested framing chain.

X-Frame-Options: DENY or SAMEORIGIN remains a simpler compatibility control, but it cannot express a modern allowlist. Setting X-Frame-Options in a meta element has no effect.

Test real embedding workflows before enforcing the rule. Payment widgets you embed are controlled by their responses; dashboards that partners embed are controlled by yours.

Build Content Security Policy from evidence

Content Security Policy (CSP) can restrict which scripts, styles, images, frames, connections, and form destinations a page may use. It can reduce the consequences of content injection. It can also break login, checkout, analytics, support widgets, and the product itself when copied blindly.

Start by inventorying what production actually loads and where forms submit. Remove integrations the product does not need. Then create a policy around intentional sources.

Useful early directives often include:

  • default-src as a fallback;
  • script-src, style-src, img-src, font-src, and connect-src for fetched resources;
  • frame-src for frames the page loads;
  • frame-ancestors for sites allowed to frame the page;
  • form-action for form destinations;
  • base-uri to restrict document base URLs;
  • object-src when legacy plugin content is unnecessary.

Do not add 'unsafe-inline', broad wildcards, or whole schemes merely to silence violations. They can remove much of the boundary you intended to create.

Deploy a Content-Security-Policy-Report-Only version first when breakage risk is meaningful. Collect reports at an endpoint designed for untrusted, high-volume input. Filter browser-extension noise and avoid placing sensitive data in report destinations. Then enforce the smallest tested policy.

MDN’s CSP reference documents the directives and their distinct roles. Treat the policy as application configuration that changes whenever a new third party is added.

Limit referrer detail deliberately

URLs sometimes contain record identifiers, search terms, campaign data, or information that never should have been in a query string. When a visitor follows a link or a page loads a third-party resource, referrer information may travel with the request.

Referrer-Policy controls how much is sent. strict-origin-when-cross-origin preserves full paths on the same origin and normally sends only the origin across sites; stricter products may choose same-origin or no-referrer.

Choose the strictest policy compatible with legitimate attribution and integrations. More importantly, stop putting secrets and sensitive personal data in URLs. A referrer policy is defense in depth, not a data model.

See MDN’s Referrer-Policy guidance for the behavior of each directive.

Deny browser powers you do not use

Permissions-Policy can restrict access to features such as camera, microphone, geolocation, and fullscreen for the page and embedded frames.

Do not paste a long denial list without checking the product. Name the capabilities you use, the origins allowed to use them, and the user action that triggers them. Deny the rest where browser support and business requirements permit.

A meeting app and a text-only launch checker should not have the same policy. The useful policy describes the product’s actual powers.

Know what headers cannot do

Headers do not replace server-side authorization, safe output handling, request validation, secure cookies, dependency maintenance, or protection against cross-site request forgery. CORS is not an authentication system. A CSP does not make an unsafe API safe.

Some old scanner checklists also reward obsolete headers. Do not enable a deprecated browser feature merely to turn a line green. Prefer current browser and OWASP guidance, and understand why each control exists.

This is why a website trust review and the AI-built app production checklist cover more than the response header block.

Roll out without breaking the launch

For each proposed header:

  1. State the browser behavior it should restrict.
  2. Identify the routes and subdomains in scope.
  3. List legitimate integrations that may be affected.
  4. Configure it in one owned layer.
  5. Test public, authenticated, error, and redirect responses.
  6. Use reporting mode where supported and useful.
  7. Deploy gradually with a rollback.
  8. Recheck the public response from outside the platform.

Test signup, login, payment, file upload, downloads, analytics, support, embeds, and any OAuth return. Watch browser console violations and server errors. A strong policy that silently blocks the primary conversion path is not launch-ready.

The practical first pass

For a typical public startup site, investigate these first:

  • one canonical HTTPS destination and a careful HSTS plan;
  • accurate Content-Type plus X-Content-Type-Options: nosniff;
  • framing control through CSP frame-ancestors, with X-Frame-Options where useful;
  • a tested CSP built from actual resource use;
  • an intentional Referrer-Policy;
  • a Permissions-Policy matched to real browser features.

Then retest after every new analytics script, payment surface, support tool, or embedded product.

The right header set is not the longest set. It is the smallest accurate account of what the browser may do on behalf of your product.