Skip to content
LyraShield AIOpen beta

Security Headers Every AI-Built App Needs

Build browser security headers from application behavior, stage CSP safely, and verify policies by route instead of chasing a score.

Untrusted output crossing layered browser response controls
On this page

Direct answer: Start with route-specific browser policy, not a copied header bundle. Enforce HTTPS, disable MIME sniffing, limit referrer detail, prevent unwanted framing, and develop a Content Security Policy from the resources the app actually loads. Observe CSP in report-only mode before enforcement, then verify every document and error route in production.

Security headers are instructions to a browser. Their value depends on the page, loaded resources, authentication model, and deployment. A header name with an ineffective value can satisfy a shallow scanner while leaving the intended risk unchanged.

The vibe coding security guide treats headers as defense in depth. They do not replace output encoding, sanitization, authorization, or secure cookies.

Start from a response that only looks protected

Vulnerable pattern. Do not deploy a CSP without matching it to the app.

Content-Security-Policy: default-src * 'unsafe-inline' 'unsafe-eval' data: blob:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

The CSP permits scripts and other resources from broad locations and retains two high-risk script exceptions. The HSTS policy commits the domain and every subdomain for a long period without showing that all of them support HTTPS. Both header names exist, but neither configuration is justified.

The OWASP Secure Headers Project documents headers and deprecated patterns. Use it as a policy reference, then adapt each value to the application’s behavior.

Why copied policies fail

Generated middleware tends to paste a generic policy. Modern applications load analytics, payment frames, fonts, images, API calls, workers, and development tooling from different origins. When the policy breaks a feature, the quickest generated fix is often *, 'unsafe-inline', or an ever-growing host list.

The opposite failure is an aspirational strict policy that was never exercised. It may block production login, error reporting, or a payment route. Teams disable it during an incident and never restore it.

Build policy from an inventory of real resource types and routes. Keep development allowances out of production. Generated script nonces must be unpredictable per response and attached only to approved script elements. A static nonce copied into every page is not a nonce.

Establish a small browser-policy baseline

For HTML documents, consider these controls and decide their exact values:

Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; script-src 'self' 'nonce-{per-response-value}'
Strict-Transport-Security: max-age=86400
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin

This is an illustration, not a ready-to-paste policy. An application that must be framed by a trusted partner cannot use frame-ancestors 'none'. A static site without inline scripts may not need nonces. Images, styles, connections, workers, and forms need directives matching their actual destinations.

X-Content-Type-Options: nosniff tells browsers not to reinterpret certain responses as a different MIME type. Still send correct Content-Type values. Referrer-Policy controls how much referring URL information is sent; avoid putting secrets in URLs regardless of that policy.

Apply document-only headers to documents deliberately. An API JSON response does not execute a page CSP, while a generated error document might. Static assets need correct MIME types and caching. Authentication and private HTML responses should not be stored in shared caches merely because the security-header middleware runs.

Different routes may need different CSP directives. A payment page can permit a reviewed frame or script that the rest of the site does not need. Prefer a narrow route policy over adding that origin to every page. Keep a small number of named policy profiles so exceptions remain reviewable.

Use CSP frame-ancestors to control which origins can embed the document. The current CSP Level 3 Working Draft specifies that it does not fall back to default-src, so declare it directly. Legacy X-Frame-Options may remain for older clients, but keep the policies consistent.

Stage CSP with real route coverage

Send Content-Security-Policy-Report-Only with the candidate policy. The CSP Working Draft defines report-only as monitoring rather than enforcement, which supports iterative deployment. Reports can contain page URLs and blocked resource information, so minimize collected fields, avoid sensitive URL data, and set retention deliberately.

Exercise the homepage, authentication, account pages, payment flows, error pages, previews, and any user-generated content. Separate extensions, injected corporate scripts, and browser tooling noise from resources the application actually requires.

Do not treat every report as an attack. A violation can come from a stale cached page, a blocked browser extension, a deployment mismatch, or real injected content. Group reports by policy version and route, sample noisy sources, and preserve enough context to reproduce the app behavior without collecting full URLs that may contain sensitive parameters.

Move directives into enforcement in controlled steps. Keep reporting during rollout where useful. Test the actual response at the CDN edge because proxies, redirects, and error handlers may replace or omit origin headers.

If HTML varies by nonce, ensure shared caching does not pair one document with another response’s policy. Generate the nonce once per response and use the same value in the header and approved elements. Do not expose it through client state for later arbitrary script creation.

A meta element has limited CSP support. The Working Draft says report-only policy, report-uri, frame-ancestors, and sandbox are not supported through that delivery form. A meta policy also applies only after the browser encounters it. Prefer the HTTP response header when possible.

Roll out HSTS without trapping subdomains

RFC 6797 defines HSTS as a policy received over secure transport that tells the user agent to use secure transport for the host during the retention period. A browser ignores the header when received over insecure HTTP.

Start with a short max-age after confirming the canonical host serves valid HTTPS and redirects correctly. Increase it only after monitoring. Add includeSubDomains only when every current and delegated subdomain can support HTTPS. Preload is a separate, higher-commitment operational decision with browser-list requirements and removal delays.

HSTS affects browsers that have learned or preloaded the policy. It does not configure TLS versions, certificates, or mobile networking libraries. Server TLS remains a separate control.

Review subdomain ownership before includeSubDomains. Old marketing hosts, customer-controlled subdomains, mail interfaces, and vendor callbacks may have different TLS operations. Inventory them and fix or retire insecure hosts first. A long HSTS lifetime is hard to reverse for browsers that already cached it.

Keep CORS, CSP, and sanitization separate

CORS decides which browser origins may read selected cross-origin responses. CSP constrains resources and embedding for a document. Neither one sanitizes HTML or validates authorization.

The CORS guide covers API response sharing. An XSS defense still needs context-appropriate output encoding and sanitization. A strict CSP can limit impact when an injection slips through, but broad trusted script origins and allowed dynamic code can weaken that layer.

Verify the response, not just configuration

Build a production-shaped local deployment or authorized staging site. Request representative HTML, JSON, redirects, 404s, and 500s. Inspect the final response after CDN and middleware processing. Confirm there are not multiple conflicting CSP or HSTS headers.

Open core user flows with browser developer tools and no extensions. Review CSP violations and network failures. Test framing from a controlled second origin. Confirm HSTS scope on disposable test hosts before expanding production duration.

The browser-local security headers checker reviews pasted response headers without uploading them. It can flag missing or risky directives. It cannot crawl every route, execute the CSP, inspect server TLS, or prove the app’s code is safe.

What a header result proves

An automated check can describe the exact headers in one response and identify policy syntax worth review. Browser tests can show that selected flows work under enforcement.

Neither result proves every route returns the same policy or every allowed origin is trustworthy. Record the URL class, status, deployed build, header value, and tested workflow. Treat a clean score as configuration evidence for that response, not a security verdict.

Sources

Frequently asked

Can Content Security Policy be set in a meta element?

An enforcing CSP can be delivered through an early meta element, but report-only policy, report-uri, frame-ancestors, and sandbox are not supported there. Prefer an HTTP response header when the server controls the response.

Why should HSTS be rolled out carefully?

Browsers cache HSTS for the declared lifetime, and includeSubDomains expands its scope. Confirm HTTPS works on every covered host before increasing max-age or requesting preload.

Does a high security-header score prove an app is secure?

No. Headers influence browser behavior. They do not prove authorization, input validation, output sanitization, session invalidation, dependency safety, or protection of non-browser clients.

  • AI App Pre-Launch Security Checklist

    Run an evidence-based pre-launch review across authorization, secrets, inputs, dependencies, deployment, agents, monitoring, recovery, and retests.

  • Secure an AI SaaS With Stripe

    Secure Stripe billing with server-owned entitlements, raw-body webhook verification, idempotent processing, constrained keys, and failure-path tests.

  • Secure a Bolt App Before Launch

    Identify the Bolt backend, protect server functions and webhooks, test database policy, and verify the published deployment.

Stay in the loop.

We store your email for product updates and scorecard notifications. No sharing, no marketing blasts.