[{"data":1,"prerenderedAt":269},["ShallowReactive",2],{"tool-content-en-security-headers-generator":3},{"id":4,"title":5,"body":6,"description":259,"extension":260,"locale":261,"meta":262,"navigation":263,"path":264,"seo":265,"stem":266,"toolId":267,"__hash__":268},"tools\u002Ftools\u002Fen\u002Fsecurity-headers-generator.md","Security Headers Generator (CSP)",{"type":7,"value":8,"toc":249},"minimark",[9,14,23,27,76,87,112,116,132,136,181,185,214,218],[10,11,13],"h2",{"id":12},"what-this-tool-does","What this tool does",[15,16,17,18,22],"p",{},"Assemble a ",[19,20,21],"code",{},"Content-Security-Policy"," from structured directive rows instead of writing the header by hand, add the other security response headers next to it, and copy the result in the format your host expects. The policy is generated on the right as you edit, and the footer checks it for the mistakes that most often make a policy useless or break a site. Everything runs in your browser.",[10,24,26],{"id":25},"directives-and-presets","Directives and presets",[15,28,29,30,33,34,33,37,40,41,33,44,33,47,50,51,54,55,58,59,62,63,33,66,33,69,33,72,75],{},"Each fetch directive (",[19,31,32],{},"default-src",", ",[19,35,36],{},"script-src",[19,38,39],{},"style-src"," and so on) is one row with a checkbox and a space-separated source list: keywords such as ",[19,42,43],{},"'self'",[19,45,46],{},"'none'",[19,48,49],{},"'unsafe-inline'"," and ",[19,52,53],{},"'strict-dynamic'"," must be quoted, host and scheme sources (",[19,56,57],{},"https:"," or ",[19,60,61],{},"https:\u002F\u002Fcdn.example.com",") must not be. The same applies to the document and navigation directives (",[19,64,65],{},"base-uri",[19,67,68],{},"form-action",[19,70,71],{},"frame-ancestors",[19,73,74],{},"sandbox",") and to the reporting directives.",[15,77,78,79,81,82,86],{},"Presets fill the directive rows for a common setup: a static site with no inline scripts, a Next.js app using a nonce with ",[19,80,53],{},", a single-page app, or a site that pulls scripts and fonts from public CDNs. They replace the directive rows only — the other response headers stay as you set them. ",[83,84,85],"strong",{},"Clear"," resets everything.",[15,88,89,90,33,93,33,96,33,99,33,102,33,105,50,108,111],{},"The rows cover the directives most policies need. ",[19,91,92],{},"script-src-elem",[19,94,95],{},"script-src-attr",[19,97,98],{},"style-src-elem",[19,100,101],{},"style-src-attr",[19,103,104],{},"child-src",[19,106,107],{},"navigate-to",[19,109,110],{},"require-trusted-types-for"," are not in the builder, so add them by hand when your policy needs them.",[10,113,115],{"id":114},"nonces-and-inline-hashes","Nonces and inline hashes",[15,117,118,119,58,121,123,124,127,128,131],{},"If your server renders a fresh nonce into each response, paste it in and add it to ",[19,120,36],{},[19,122,39],{}," as ",[19,125,126],{},"'nonce-…'",". A generated example is only a placeholder: a real nonce must be new for every response, so the audit reminds you when a placeholder is still in the policy. For inline scripts and styles you cannot move into a file, paste the exact contents into the hash box to get a ",[19,129,130],{},"'sha256-…'"," source, then add it to either directive.",[10,133,135],{"id":134},"other-security-headers","Other security headers",[15,137,138,139,142,143,33,146,33,149,152,153,33,156,50,159,162,163,166,167,170,171,33,174,58,177,180],{},"Next to the CSP you can enable ",[19,140,141],{},"X-Content-Type-Options: nosniff",", a ",[19,144,145],{},"Referrer-Policy",[19,147,148],{},"X-Frame-Options",[19,150,151],{},"Strict-Transport-Security"," with its ",[19,154,155],{},"max-age",[19,157,158],{},"includeSubDomains",[19,160,161],{},"preload"," options, the cross-origin isolation headers (COOP, COEP, CORP), a ",[19,164,165],{},"Reporting-Endpoints"," value, and a ",[19,168,169],{},"Permissions-Policy"," where each browser feature is set to ",[19,172,173],{},"()",[19,175,176],{},"(self)",[19,178,179],{},"*",".",[10,182,184],{"id":183},"checking-the-policy","Checking the policy",[15,186,187,188,58,190,193,194,33,197,58,199,202,203,33,206,58,208,210,211,213],{},"The footer lists what it finds, from high to informational: ",[19,189,49],{},[19,191,192],{},"'unsafe-eval'"," in a script directive, plain ",[19,195,196],{},"http:",[19,198,57],{},[19,200,201],{},"data:"," schemes where they enable XSS, a missing ",[19,204,205],{},"object-src",[19,207,36],{},[19,209,65],{},", host allowlists that are easy to bypass, nonces that are too short, deprecated directives, and a missing reporting destination. Sources that a nonce or ",[19,212,53],{}," makes browsers ignore are reported as notes rather than problems, because the policy itself is fine.",[10,215,217],{"id":216},"exporting","Exporting",[15,219,220,221,224,225,228,229,232,233,236,237,240,241,244,245,248],{},"Pick the target: raw response headers, an HTML ",[19,222,223],{},"\u003Cmeta>"," tag (CSP only, since a meta element cannot deliver Report-Only or the other headers), nginx ",[19,226,227],{},"add_header",", a Cloudflare Pages or Netlify ",[19,230,231],{},"_headers"," file, Apache ",[19,234,235],{},"Header always set",", or ",[19,238,239],{},"vercel.json",". ",[83,242,243],{},"Copy"," puts the result on the clipboard and ",[83,246,247],{},"Download"," saves it under the matching filename. Your policy is remembered on this device when tool memory is enabled.",{"title":250,"searchDepth":251,"depth":251,"links":252},"",2,[253,254,255,256,257,258],{"id":12,"depth":251,"text":13},{"id":25,"depth":251,"text":26},{"id":114,"depth":251,"text":115},{"id":134,"depth":251,"text":135},{"id":183,"depth":251,"text":184},{"id":216,"depth":251,"text":217},"Build a Content-Security-Policy from directives, audit it for common mistakes, and export it for nginx, Cloudflare Pages, Apache or vercel.json.","md","en",{},true,"\u002Ftools\u002Fen\u002Fsecurity-headers-generator",{"title":5,"description":259},"tools\u002Fen\u002Fsecurity-headers-generator","security-headers-generator","f3bAlN8nYd8KtvwIQmaSzH0gBm7NWD2sxmvpjZVggjA",1792391420442]