Developer Tools
Security Headers Generator
Build HTTP security headers in your browser. CSP, HSTS, Referrer-Policy, Permissions-Policy, COOP, COEP, CORP with Nginx, Apache, Vercel, and Netlify snippets.
Quick presets
Tap a preset to load a recommended baseline, then tune below.
Hardening score
Weighted by impact across the headers OWASP and web.dev recommend.
100%
8 of 8 recommended headers enabled.
Content-Security-Policy
The single most effective defense against XSS. Lists allowed sources for scripts, styles, images, and connections.
Strict-Transport-Security
Forces HTTPS for this domain. Once seen, browsers refuse plain HTTP until max-age expires.
X-Frame-Options
Stops clickjacking by forbidding (or restricting) iframe embedding. Superseded by CSP frame-ancestors but still recognized by older browsers.
X-Content-Type-Options
Always emits nosniff. Stops browsers from interpreting files as a different MIME type than the server declared.
X-Content-Type-Options: nosniff
Referrer-Policy
Controls how much of the originating URL is sent on outbound requests and link clicks.
Permissions-Policy
Allowlist of browser features. Pick (self), (*), or () for each capability.
Cross-Origin-Opener-Policy
Isolates this page's browsing-context group from cross-origin windows. Needed for high-precision timers and SharedArrayBuffer.
Cross-Origin-Embedder-Policy
Requires every resource loaded into this page to opt in via CORP or CORS. Pair with COOP same-origin for cross-origin isolation.
Cross-Origin-Resource-Policy
Limits who can load this response cross-origin. same-site and same-origin are the common picks.
X-XSS-Protection (legacy)
Sends the value 0 to disable the deprecated XSS auditor. Modern browsers ignore this header; CSP is the right defense today.
X-XSS-Protection: 0
Recommendations
- infoCSP frame-ancestors is set, so X-Frame-Options is redundant. Browsers that support both ignore X-Frame-Options when CSP frame-ancestors is present.
Generated headers (8)
Content-Security-Policy
default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'
Strict-Transport-Security
max-age=31536000; includeSubDomains
X-Frame-Options
SAMEORIGIN
X-Content-Type-Options
nosniff
Referrer-Policy
strict-origin-when-cross-origin
Permissions-Policy
camera=(self), microphone=(self), geolocation=(self), fullscreen=(self), payment=(self), usb=(self), midi=(self), clipboard-read=(self), clipboard-write=(self), interest-cohort=(), accelerometer=(self), gyroscope=(self), magnetometer=(self), autoplay=(self), encrypted-media=(self), display-capture=(self)
Cross-Origin-Opener-Policy
same-origin
Cross-Origin-Resource-Policy
same-origin
Nginx
server {
# Place inside server { } or location { } blocks.
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(self), microphone=(self), geolocation=(self), fullscreen=(self), payment=(self), usb=(self), midi=(self), clipboard-read=(self), clipboard-write=(self), interest-cohort=(), accelerometer=(self), gyroscope=(self), magnetometer=(self), autoplay=(self), encrypted-media=(self), display-capture=(self)" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;
}Apache (.htaccess)
<IfModule mod_headers.c> Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Permissions-Policy "camera=(self), microphone=(self), geolocation=(self), fullscreen=(self), payment=(self), usb=(self), midi=(self), clipboard-read=(self), clipboard-write=(self), interest-cohort=(), accelerometer=(self), gyroscope=(self), magnetometer=(self), autoplay=(self), encrypted-media=(self), display-capture=(self)" Header always set Cross-Origin-Opener-Policy "same-origin" Header always set Cross-Origin-Resource-Policy "same-origin" </IfModule>
Caddyfile
example.com {
header {
Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Frame-Options SAMEORIGIN
X-Content-Type-Options nosniff
Referrer-Policy strict-origin-when-cross-origin
Permissions-Policy "camera=(self), microphone=(self), geolocation=(self), fullscreen=(self), payment=(self), usb=(self), midi=(self), clipboard-read=(self), clipboard-write=(self), interest-cohort=(), accelerometer=(self), gyroscope=(self), magnetometer=(self), autoplay=(self), encrypted-media=(self), display-capture=(self)"
Cross-Origin-Opener-Policy same-origin
Cross-Origin-Resource-Policy same-origin
}
}Netlify and Cloudflare Pages (_headers)
/* Content-Security-Policy: default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self' Strict-Transport-Security: max-age=31536000; includeSubDomains X-Frame-Options: SAMEORIGIN X-Content-Type-Options: nosniff Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(self), microphone=(self), geolocation=(self), fullscreen=(self), payment=(self), usb=(self), midi=(self), clipboard-read=(self), clipboard-write=(self), interest-cohort=(), accelerometer=(self), gyroscope=(self), magnetometer=(self), autoplay=(self), encrypted-media=(self), display-capture=(self) Cross-Origin-Opener-Policy: same-origin Cross-Origin-Resource-Policy: same-origin
Vercel (vercel.json)
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"
},
{
"key": "Strict-Transport-Security",
"value": "max-age=31536000; includeSubDomains"
},
{
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
},
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "Referrer-Policy",
"value": "strict-origin-when-cross-origin"
},
{
"key": "Permissions-Policy",
"value": "camera=(self), microphone=(self), geolocation=(self), fullscreen=(self), payment=(self), usb=(self), midi=(self), clipboard-read=(self), clipboard-write=(self), interest-cohort=(), accelerometer=(self), gyroscope=(self), magnetometer=(self), autoplay=(self), encrypted-media=(self), display-capture=(self)"
},
{
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin"
},
{
"key": "Cross-Origin-Resource-Policy",
"value": "same-origin"
}
]
}
]
}Express.js and Node.js
// Express.js or any Node.js HTTP handler.
app.use((req, res, next) => {
res.setHeader("Content-Security-Policy", "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'");
res.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
res.setHeader("X-Frame-Options", "SAMEORIGIN");
res.setHeader("X-Content-Type-Options", "nosniff");
res.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
res.setHeader("Permissions-Policy", "camera=(self), microphone=(self), geolocation=(self), fullscreen=(self), payment=(self), usb=(self), midi=(self), clipboard-read=(self), clipboard-write=(self), interest-cohort=(), accelerometer=(self), gyroscope=(self), magnetometer=(self), autoplay=(self), encrypted-media=(self), display-capture=(self)");
res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
res.setHeader("Cross-Origin-Resource-Policy", "same-origin");
next();
});Raw HTTP response
Content-Security-Policy: default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self' Strict-Transport-Security: max-age=31536000; includeSubDomains X-Frame-Options: SAMEORIGIN X-Content-Type-Options: nosniff Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(self), microphone=(self), geolocation=(self), fullscreen=(self), payment=(self), usb=(self), midi=(self), clipboard-read=(self), clipboard-write=(self), interest-cohort=(), accelerometer=(self), gyroscope=(self), magnetometer=(self), autoplay=(self), encrypted-media=(self), display-capture=(self) Cross-Origin-Opener-Policy: same-origin Cross-Origin-Resource-Policy: same-origin
HTML <meta> equivalents
<!-- Only CSP, Referrer-Policy, and X-Content-Type-Options have a documented <meta http-equiv> form. --> <meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"> <meta http-equiv="X-Content-Type-Options" content="nosniff"> <meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin"> <!-- Strict-Transport-Security cannot be set via <meta>. Send it as an HTTP response header. --> <!-- X-Frame-Options cannot be set via <meta>. Send it as an HTTP response header. --> <!-- Permissions-Policy cannot be set via <meta>. Send it as an HTTP response header. --> <!-- Cross-Origin-Opener-Policy cannot be set via <meta>. Send it as an HTTP response header. --> <!-- Cross-Origin-Resource-Policy cannot be set via <meta>. Send it as an HTTP response header. -->
Quick reference
CSP vs frame-ancestors vs X-Frame-Options
Use a CSP with frame-ancestors as the modern choice. Keep X-Frame-Options for older browsers; modern engines ignore it when CSP frame-ancestors is present.
HSTS preload requirements
max-age of at least 31536000 (1 year), includeSubDomains, preload directive, and HTTPS on every subdomain. Submit at hstspreload.org.
Cross-origin isolation
Set COOP: same-origin and COEP: require-corp together. Enables SharedArrayBuffer and high-resolution timers but blocks cross-origin iframes and resources.
Permissions-Policy values
(self) allows the feature for this origin and same-origin iframes. (*) allows it for any origin. () denies it everywhere, including the page itself.
How to use
- Pick a preset (Strict, Balanced, or Starter) to load a recommended baseline, then tune individual headers below.
- Toggle each header on or off using the switch in its panel. Edit the Content-Security-Policy directly in the textarea; use Report-Only mode while you tune it.
- Adjust HSTS max-age with the 6-month, 1-year, or 2-year preset, and toggle includeSubDomains and preload if you intend to submit to the HSTS preload list.
- Use the Permissions-Policy capability grid to pick (self), (*), or () per feature, or use the bulk buttons at the top to set them all at once.
- Read the hardening score and the recommendations panel. Warnings highlight insecure or contradictory choices like preload without includeSubDomains or COEP without COOP.
- Scroll to Generated headers to copy a single header line, or pick the snippet for your server: Nginx, Apache, Caddy, Netlify and Cloudflare Pages _headers, Vercel vercel.json, Express.js, raw HTTP, or HTML <meta>.
About this tool
Security Headers Generator builds the response header set that the OWASP Secure Headers Project and web.dev recommend for hardening a website, then emits ready-to-paste snippets for every common deployment target. Each header is a small structured panel you can toggle on or off: Content-Security-Policy (with a Report-Only toggle and a generous default policy you can edit), Strict-Transport-Security (max-age field with 6-month, 1-year, and 2-year presets, plus includeSubDomains and preload switches), X-Frame-Options (DENY or SAMEORIGIN), X-Content-Type-Options (always nosniff), Referrer-Policy (all eight standardized values with a one-line explanation of what each leaks), Permissions-Policy (sixteen browser capabilities including camera, microphone, geolocation, fullscreen, payment, clipboard read and write, interest-cohort, and the motion sensors, each switchable between (self), (*), and ()), Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy, and Cross-Origin-Resource-Policy for cross-origin isolation, and the legacy X-XSS-Protection header which sends 0 to disable the deprecated XSS auditor that modern browsers no longer use. Three quick presets seed the form: Strict applies the cross-origin isolated configuration with a tight CSP, two-year HSTS preload, no referrer leakage, and every browser capability denied; Balanced applies the web.dev defaults that work for most apps without breaking inline styles; Starter adds HSTS, X-Frame-Options, nosniff, and a sane Referrer-Policy without setting a CSP. A live hardening score weighs the most impactful headers (CSP, HSTS with preload-eligible max-age, nosniff, frame protection, modern Referrer-Policy, COOP, CORP) and shows a strong, good, OK, or weak band so you can see at a glance whether the configuration is shippable. An inline recommendation panel flags conflicts and quiet failures: HSTS preload submitted without includeSubDomains, max-age too low for the preload list, COEP enabled without COOP (which silently fails to enable cross-origin isolation), CSP frame-ancestors set while X-Frame-Options is also on (redundant), 'unsafe-inline' shadowed by a nonce, missing default-src in the CSP, and Referrer-Policy values that leak full URLs cross-origin. Output is rendered in eight formats so you can copy straight into your stack: Nginx (add_header with always), Apache .htaccess (Header always set inside mod_headers), Caddyfile (header block), Netlify and Cloudflare Pages _headers file, Vercel vercel.json headers array, Express.js and Node.js middleware (res.setHeader), a raw HTTP response section, and the HTML <meta http-equiv> equivalents for the three headers (CSP, Referrer-Policy, nosniff) that have a documented meta form, with explicit comments marking which headers cannot be set this way. Everything happens locally in your browser. The policies, internal hostnames, and report-uri endpoints you type into the CSP editor never leave your device, which matters because in-progress security configurations often reference origins that you do not want to leak to a third-party tool.
Free to use. Works in your browser. No signup, no login.
Related tools
You may also like
CSP Header Generator
Visual builder for the Content-Security-Policy HTTP header.
Open tool
DeveloperCSP Analyzer
Audit a Content-Security-Policy header for known bypasses and missing defenses.
Open tool
DeveloperCache-Control Header Builder
Build and parse Cache-Control headers with directive flags, max-age presets, conflict checks, and ready-to-paste server snippets.
Open tool
DeveloperHTTP Headers Parser
Parse, classify, and decode HTTP headers, with a missing security headers audit.
Open tool
DeveloperCORS Preflight Simulator
See whether a cross-origin request passes the browser CORS algorithm and why.
Open tool
SEOsecurity.txt Generator
Build an RFC 9116 security.txt with required Contact and Expires fields validated live.
Open tool