[{"data":1,"prerenderedAt":871},["ShallowReactive",2],{"blog-how-to/csp-setup":3},{"id":4,"title":5,"body":6,"category":840,"date":841,"dateModified":841,"description":842,"draft":843,"extension":844,"faq":845,"featured":843,"headerVariant":857,"image":858,"keywords":858,"meta":859,"navigation":860,"ogDescription":861,"ogTitle":858,"path":862,"readTime":858,"schemaOrg":863,"schemaType":864,"seo":865,"sitemap":866,"stem":867,"tags":868,"twitterCard":869,"__hash__":870},"blog/blog/how-to/csp-setup.md","How to Set Up Content Security Policy (CSP)",{"type":7,"value":8,"toc":803},"minimark",[9,13,17,21,39,44,60,64,67,76,80,237,241,269,285,301,338,363,399,419,469,473,477,483,487,493,499,503,509,513,519,523,527,542,546,555,559,565,569,572,578,582,586,609,613,639,643,668,672,700,704,721,729,733,767,779],[10,11],"category-badge",{"category":12},"How-To Guide",[14,15,5],"h1",{"id":16},"how-to-set-up-content-security-policy-csp",[18,19,20],"p",{},"The most powerful security header - configured correctly",[22,23,24,27],"tldr",{},[18,25,26],{},"TL;DR (25 minutes)",[18,28,29,30,34,35,38],{},"Content Security Policy prevents XSS by controlling which resources can load. Start with ",[31,32,33],"code",{},"Content-Security-Policy-Report-Only"," to test without breaking your site. Use ",[31,36,37],{},"default-src 'self'"," as your baseline, add nonces for inline scripts, and include third-party domains only where needed. Monitor violations with report-uri before switching to enforced mode.",[40,41,43],"h2",{"id":42},"prerequisites","Prerequisites",[45,46,47,51,54,57],"ul",{},[48,49,50],"li",{},"Ability to set HTTP headers (via server config, middleware, or hosting platform)",[48,52,53],{},"Understanding of what resources your app loads (scripts, styles, images, fonts)",[48,55,56],{},"Access to browser DevTools for testing",[48,58,59],{},"Optional: A reporting endpoint for CSP violations",[40,61,63],{"id":62},"what-is-content-security-policy","What is Content Security Policy?",[18,65,66],{},"CSP is an HTTP header that tells browsers which sources of content are trusted. When a resource violates the policy, the browser blocks it and optionally reports the violation.",[68,69,70,73],"tip-box",{},[18,71,72],{},"Why CSP Matters",[18,74,75],{},"Even if an attacker injects malicious code into your page (via XSS or compromised dependencies), CSP prevents it from executing if it doesn't match your policy. It's your last line of defense against script injection.",[40,77,79],{"id":78},"csp-directive-reference","CSP Directive Reference",[81,82,83,99],"table",{},[84,85,86],"thead",{},[87,88,89,93,96],"tr",{},[90,91,92],"th",{},"Directive",[90,94,95],{},"Controls",[90,97,98],{},"Example",[100,101,102,114,125,136,147,164,178,192,203,214,227],"tbody",{},[87,103,104,108,111],{},[105,106,107],"td",{},"default-src",[105,109,110],{},"Fallback for all resource types",[105,112,113],{},"'self'",[87,115,116,119,122],{},[105,117,118],{},"script-src",[105,120,121],{},"JavaScript sources",[105,123,124],{},"'self' 'nonce-abc'",[87,126,127,130,133],{},[105,128,129],{},"style-src",[105,131,132],{},"CSS sources",[105,134,135],{},"'self' 'unsafe-inline'",[87,137,138,141,144],{},[105,139,140],{},"img-src",[105,142,143],{},"Image sources",[105,145,146],{},"'self' data: https:",[87,148,149,152,155],{},[105,150,151],{},"font-src",[105,153,154],{},"Font sources",[105,156,157,158],{},"'self' ",[159,160,161],"a",{"href":161,"rel":162},"https://fonts.gstatic.com",[163],"nofollow",[87,165,166,169,172],{},[105,167,168],{},"connect-src",[105,170,171],{},"XHR, WebSocket, fetch() URLs",[105,173,157,174],{},[159,175,176],{"href":176,"rel":177},"https://api.example.com",[163],[87,179,180,183,186],{},[105,181,182],{},"frame-src",[105,184,185],{},"iframe sources",[105,187,157,188],{},[159,189,190],{"href":190,"rel":191},"https://youtube.com",[163],[87,193,194,197,200],{},[105,195,196],{},"frame-ancestors",[105,198,199],{},"Who can embed this page",[105,201,202],{},"'none' or 'self'",[87,204,205,208,211],{},[105,206,207],{},"object-src",[105,209,210],{},"Flash, plugins",[105,212,213],{},"'none'",[87,215,216,219,225],{},[105,217,218],{},"base-uri",[105,220,221,224],{},[222,223],"base",{}," tag URLs",[105,226,113],{},[87,228,229,232,235],{},[105,230,231],{},"form-action",[105,233,234],{},"Form submission URLs",[105,236,113],{},[40,238,240],{"id":239},"step-by-step-implementation","Step-by-Step Implementation",[242,243,245,250,256,266],"step",{"number":244},"1",[246,247,249],"h3",{"id":248},"start-with-report-only-mode","Start with Report-Only Mode",[18,251,252,253,255],{},"Use ",[31,254,33],{}," to test without breaking your site:",[257,258,263],"pre",{"className":259,"code":261,"language":262},[260],"language-text","Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report\n","text",[31,264,261],{"__ignoreMap":265},"",[18,267,268],{},"This logs violations to the console and your reporting endpoint without blocking anything.",[242,270,272,276,279],{"number":271},"2",[246,273,275],{"id":274},"build-your-base-policy","Build Your Base Policy",[18,277,278],{},"Start strict and add exceptions as needed:",[257,280,283],{"className":281,"code":282,"language":262},[260],"Content-Security-Policy:\n  default-src 'self';\n  script-src 'self';\n  style-src 'self';\n  img-src 'self';\n  font-src 'self';\n  connect-src 'self';\n  frame-src 'none';\n  object-src 'none';\n  base-uri 'self';\n  form-action 'self';\n  frame-ancestors 'none';\n  upgrade-insecure-requests;\n",[31,284,282],{"__ignoreMap":265},[242,286,288,292,295],{"number":287},"3",[246,289,291],{"id":290},"add-third-party-resources","Add Third-Party Resources",[18,293,294],{},"Identify and allow external resources your app needs:",[257,296,299],{"className":297,"code":298,"language":262},[260],"Content-Security-Policy:\n  default-src 'self';\n  script-src 'self' https://cdn.jsdelivr.net https://www.googletagmanager.com;\n  style-src 'self' https://fonts.googleapis.com;\n  img-src 'self' data: https: blob:;\n  font-src 'self' https://fonts.gstatic.com;\n  connect-src 'self' https://api.example.com https://analytics.example.com;\n  frame-src https://www.youtube.com https://player.vimeo.com;\n  object-src 'none';\n  base-uri 'self';\n  form-action 'self';\n  frame-ancestors 'none';\n",[31,300,298],{"__ignoreMap":265},[242,302,304,308,315,321,327,332],{"number":303},"4",[246,305,307],{"id":306},"implement-nonces-for-inline-scripts","Implement Nonces for Inline Scripts",[18,309,310,311,314],{},"Instead of using ",[31,312,313],{},"'unsafe-inline'",", use nonces:",[18,316,317],{},[318,319,320],"strong",{},"Generate a unique nonce for each request:",[257,322,325],{"className":323,"code":324,"language":262},[260],"// Express.js middleware\nconst crypto = require('crypto');\n\napp.use((req, res, next) => {\n  res.locals.nonce = crypto.randomBytes(16).toString('base64');\n  next();\n});\n\napp.use((req, res, next) => {\n  const nonce = res.locals.nonce;\n  res.setHeader('Content-Security-Policy',\n    `default-src 'self'; ` +\n    `script-src 'self' 'nonce-${nonce}' 'strict-dynamic'; ` +\n    `style-src 'self' 'nonce-${nonce}';`\n  );\n  next();\n});\n",[31,326,324],{"__ignoreMap":265},[18,328,329],{},[318,330,331],{},"Add nonce to your inline scripts:",[257,333,336],{"className":334,"code":335,"language":262},[260],"\u003C!-- In your HTML template -->\n\u003Cscript nonce=\"\u003C%= nonce %>\">\n  // This inline script will execute\n  console.log('Authorized inline script');\n\u003C/script>\n\n\u003Cscript>\n  // This will be BLOCKED - no nonce\n  console.log('Unauthorized script');\n\u003C/script>\n",[31,337,335],{"__ignoreMap":265},[242,339,341,345,348,354,357],{"number":340},"5",[246,342,344],{"id":343},"use-hashes-for-static-inline-scripts-alternative","Use Hashes for Static Inline Scripts (Alternative)",[18,346,347],{},"For static inline scripts that don't change, use hashes:",[257,349,352],{"className":350,"code":351,"language":262},[260],"# Generate hash of your inline script\necho -n \"console.log('Hello');\" | openssl dgst -sha256 -binary | openssl base64\n# Output: 5jFwrAK0UV47oFbVg/iCCBbxD8X1w+QvoOUepu4C2YA=\n",[31,353,351],{"__ignoreMap":265},[18,355,356],{},"Add the hash to your CSP:",[257,358,361],{"className":359,"code":360,"language":262},[260],"Content-Security-Policy: script-src 'self' 'sha256-5jFwrAK0UV47oFbVg/iCCBbxD8X1w+QvoOUepu4C2YA=';\n",[31,362,360],{"__ignoreMap":265},[242,364,366,370,373,379,382,388,393],{"number":365},"6",[246,367,369],{"id":368},"set-up-violation-reporting","Set Up Violation Reporting",[18,371,372],{},"Create an endpoint to receive CSP violation reports:",[257,374,377],{"className":375,"code":376,"language":262},[260],"// Express.js endpoint for CSP reports\napp.post('/csp-report', express.json({ type: 'application/csp-report' }), (req, res) => {\n  const report = req.body['csp-report'];\n  console.log('CSP Violation:', {\n    blockedUri: report['blocked-uri'],\n    violatedDirective: report['violated-directive'],\n    documentUri: report['document-uri'],\n    sourceFile: report['source-file'],\n    lineNumber: report['line-number'],\n  });\n\n  // Send to your logging service\n  // await logService.log('csp-violation', report);\n\n  res.status(204).end();\n});\n",[31,378,376],{"__ignoreMap":265},[18,380,381],{},"Add report-uri to your CSP:",[257,383,386],{"className":384,"code":385,"language":262},[260],"Content-Security-Policy: default-src 'self'; report-uri /csp-report;\n",[31,387,385],{"__ignoreMap":265},[18,389,390],{},[318,391,392],{},"Modern reporting with report-to:",[257,394,397],{"className":395,"code":396,"language":262},[260],"# Headers\nReport-To: {\"group\":\"csp-endpoint\",\"max_age\":10886400,\"endpoints\":[{\"url\":\"/csp-report\"}]}\nContent-Security-Policy: default-src 'self'; report-to csp-endpoint;\n",[31,398,396],{"__ignoreMap":265},[242,400,402,406,413],{"number":401},"7",[246,403,405],{"id":404},"switch-to-enforced-mode","Switch to Enforced Mode",[18,407,408,409,412],{},"Once violations are resolved, remove ",[31,410,411],{},"-Report-Only"," from the header:",[257,414,417],{"className":415,"code":416,"language":262},[260],"# Before (testing)\nContent-Security-Policy-Report-Only: default-src 'self'; ...\n\n# After (enforced)\nContent-Security-Policy: default-src 'self'; ...\n",[31,418,416],{"__ignoreMap":265},[420,421,422,425],"warning-box",{},[18,423,424],{},"CSP Security Checklist",[45,426,427,433,440,447,456,463,466],{},[48,428,429,430,432],{},"Never use ",[31,431,313],{}," for script-src if possible - use nonces instead",[48,434,435,436,439],{},"Avoid ",[31,437,438],{},"'unsafe-eval'"," unless absolutely required (some frameworks need it)",[48,441,442,443,446],{},"Always include ",[31,444,445],{},"object-src 'none'"," to block Flash/plugins",[48,448,252,449,452,453,455],{},[31,450,451],{},"frame-ancestors 'none'"," or ",[31,454,113],{}," to prevent clickjacking",[48,457,458,459,462],{},"Include ",[31,460,461],{},"base-uri 'self'"," to prevent base tag hijacking",[48,464,465],{},"Test thoroughly in report-only mode before enforcing",[48,467,468],{},"Monitor violation reports after deployment",[40,470,472],{"id":471},"common-csp-configurations","Common CSP Configurations",[246,474,476],{"id":475},"strict-csp-for-modern-apps","Strict CSP for Modern Apps",[257,478,481],{"className":479,"code":480,"language":262},[260],"Content-Security-Policy:\n  default-src 'self';\n  script-src 'self' 'nonce-{random}' 'strict-dynamic';\n  style-src 'self' 'nonce-{random}';\n  img-src 'self' data: https:;\n  font-src 'self';\n  connect-src 'self' https://api.yoursite.com;\n  frame-src 'none';\n  object-src 'none';\n  base-uri 'self';\n  form-action 'self';\n  frame-ancestors 'none';\n  upgrade-insecure-requests;\n",[31,482,480],{"__ignoreMap":265},[246,484,486],{"id":485},"nextjs-react-application","Next.js / React Application",[257,488,491],{"className":489,"code":490,"language":262},[260],"Content-Security-Policy:\n  default-src 'self';\n  script-src 'self' 'unsafe-eval' 'unsafe-inline';\n  style-src 'self' 'unsafe-inline';\n  img-src 'self' data: blob: https:;\n  font-src 'self' https://fonts.gstatic.com;\n  connect-src 'self' wss: https:;\n  frame-src 'self';\n  object-src 'none';\n  base-uri 'self';\n  form-action 'self';\n  frame-ancestors 'self';\n",[31,492,490],{"__ignoreMap":265},[18,494,495],{},[496,497,498],"em",{},"Note: 'unsafe-eval' is needed for development hot reloading. Consider removing in production.",[246,500,502],{"id":501},"static-marketing-site","Static Marketing Site",[257,504,507],{"className":505,"code":506,"language":262},[260],"Content-Security-Policy:\n  default-src 'self';\n  script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com;\n  style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;\n  img-src 'self' data: https:;\n  font-src 'self' https://fonts.gstatic.com;\n  connect-src 'self' https://www.google-analytics.com;\n  frame-src https://www.youtube.com;\n  object-src 'none';\n  base-uri 'self';\n  form-action 'self' https://formsubmit.co;\n  frame-ancestors 'none';\n  upgrade-insecure-requests;\n",[31,508,506],{"__ignoreMap":265},[246,510,512],{"id":511},"e-commerce-with-payment-integration","E-commerce with Payment Integration",[257,514,517],{"className":515,"code":516,"language":262},[260],"Content-Security-Policy:\n  default-src 'self';\n  script-src 'self' https://js.stripe.com https://www.paypal.com;\n  style-src 'self' 'unsafe-inline';\n  img-src 'self' data: https: blob:;\n  font-src 'self' https://fonts.gstatic.com;\n  connect-src 'self' https://api.stripe.com https://api.yoursite.com;\n  frame-src https://js.stripe.com https://www.paypal.com;\n  object-src 'none';\n  base-uri 'self';\n  form-action 'self' https://api.stripe.com;\n  frame-ancestors 'none';\n",[31,518,516],{"__ignoreMap":265},[40,520,522],{"id":521},"how-to-verify-it-worked","How to Verify It Worked",[246,524,526],{"id":525},"method-1-browser-console","Method 1: Browser Console",[528,529,530,533,536,539],"ol",{},[48,531,532],{},"Open DevTools (F12)",[48,534,535],{},"Go to Console tab",[48,537,538],{},"Look for CSP violation errors (red text mentioning \"Refused to...\")",[48,540,541],{},"Each violation shows what was blocked and why",[246,543,545],{"id":544},"method-2-csp-evaluator","Method 2: CSP Evaluator",[18,547,548,549,554],{},"Use Google's ",[159,550,553],{"href":551,"rel":552},"https://csp-evaluator.withgoogle.com/",[163],"CSP Evaluator"," to analyze your policy for weaknesses.",[246,556,558],{"id":557},"method-3-security-headers-scanner","Method 3: Security Headers Scanner",[257,560,563],{"className":561,"code":562,"language":262},[260],"# Check your CSP header\ncurl -I https://yoursite.com | grep -i content-security-policy\n",[31,564,562],{"__ignoreMap":265},[246,566,568],{"id":567},"method-4-test-xss-is-blocked","Method 4: Test XSS is Blocked",[18,570,571],{},"Try injecting a script via URL parameters (if your app reflects user input):",[257,573,576],{"className":574,"code":575,"language":262},[260],"# This should be blocked by CSP\nhttps://yoursite.com/search?q=\u003Cscript>alert('xss')\u003C/script>\n",[31,577,575],{"__ignoreMap":265},[40,579,581],{"id":580},"common-errors-and-troubleshooting","Common Errors and Troubleshooting",[246,583,585],{"id":584},"inline-scripts-blocked","Inline scripts blocked",[45,587,588,594,600],{},[48,589,590,593],{},[318,591,592],{},"Solution A",": Add nonces to inline scripts",[48,595,596,599],{},[318,597,598],{},"Solution B",": Move inline scripts to external files",[48,601,602,605,606,608],{},[318,603,604],{},"Solution C",": Use ",[31,607,313],{}," (weakens security)",[246,610,612],{"id":611},"third-party-scripts-blocked","Third-party scripts blocked",[45,614,615,621,630],{},[48,616,617,620],{},[318,618,619],{},"Identify the domain",": Check console for the blocked URL",[48,622,623,626,627],{},[318,624,625],{},"Add to script-src",": ",[31,628,629],{},"script-src 'self' https://cdn.example.com",[48,631,632,635,636],{},[318,633,634],{},"Check subdomains",": You might need ",[31,637,638],{},"https://*.example.com",[246,640,642],{"id":641},"styles-not-loading","Styles not loading",[45,644,645,654,660],{},[48,646,647,650,651,653],{},[318,648,649],{},"Inline styles",": Add ",[31,652,313],{}," to style-src or use nonces",[48,655,656,659],{},[318,657,658],{},"External stylesheets",": Add the stylesheet domain to style-src",[48,661,662,665,666],{},[318,663,664],{},"CSS-in-JS",": Many libraries require ",[31,667,313],{},[246,669,671],{"id":670},"images-not-loading","Images not loading",[45,673,674,683,692],{},[48,675,676,650,679,682],{},[318,677,678],{},"Base64 images",[31,680,681],{},"data:"," to img-src",[48,684,685,650,688,691],{},[318,686,687],{},"External images",[31,689,690],{},"https:"," or specific domains",[48,693,694,650,697,682],{},[318,695,696],{},"Blob URLs",[31,698,699],{},"blob:",[246,701,703],{"id":702},"api-calls-blocked","API calls blocked",[45,705,706,712],{},[48,707,708,711],{},[318,709,710],{},"Fetch/XHR",": Add API domain to connect-src",[48,713,714,650,717,720],{},[318,715,716],{},"WebSockets",[31,718,719],{},"wss:"," and WebSocket URL to connect-src",[68,722,723,726],{},[18,724,725],{},"Pro Tip: Iterative CSP Development",[18,727,728],{},"Start with the most permissive working policy, then gradually tighten it. Use report-only mode and violation logs to identify what needs to be allowed. Aim to remove 'unsafe-inline' and 'unsafe-eval' over time.",[40,730,732],{"id":731},"frequently-asked-questions","Frequently Asked Questions",[734,735,736,743,749,755,761],"faq-section",{},[737,738,740],"faq-item",{"question":739},"What is Content Security Policy (CSP)?",[18,741,742],{},"CSP is an HTTP header that tells browsers which content sources are allowed on your page. It prevents XSS attacks by blocking unauthorized scripts, styles, images, and other resources from loading or executing.",[737,744,746],{"question":745},"Why does my CSP break my website?",[18,747,748],{},"CSP blocks content that doesn't match your policy. Common issues: inline scripts blocked (use nonces), third-party resources blocked (add their domains), or eval() calls blocked (add 'unsafe-eval'). Check browser console for specific violations.",[737,750,752],{"question":751},"Should I use 'unsafe-inline' in my CSP?",[18,753,754],{},"'unsafe-inline' significantly weakens XSS protection. Use nonces or hashes for inline scripts instead. For styles, 'unsafe-inline' is often needed for CSS-in-JS libraries, but migrate to external stylesheets when possible.",[737,756,758],{"question":757},"What is a CSP nonce and how does it work?",[18,759,760],{},"A nonce is a random, one-time value generated for each request. Add it to your CSP header (script-src 'nonce-abc123') and to each authorized inline script (nonce=\"abc123\"). Only scripts with matching nonces execute.",[737,762,764],{"question":763},"What is the difference between report-only and enforced mode?",[18,765,766],{},"Content-Security-Policy blocks violations. Content-Security-Policy-Report-Only only reports them without blocking. Start with report-only to identify issues, then switch to enforced once your policy is correct.",[768,769,772,776],"cta-box",{"href":770,"label":771},"/","Start Free Scan",[40,773,775],{"id":774},"test-your-csp-configuration","Test Your CSP Configuration",[18,777,778],{},"Scan your site to check if CSP is configured correctly and identify potential weaknesses.",[780,781,782,788,793,798],"related-articles",{},[783,784],"related-card",{"description":785,"href":786,"title":787},"Complete guide to all essential security headers.","/blog/how-to/add-security-headers","Security Headers Overview",[783,789],{"description":790,"href":791,"title":792},"Comprehensive XSS prevention strategies.","/blog/how-to/protect-against-xss","Protect Against XSS",[783,794],{"description":795,"href":796,"title":797},"Implement CSP with nonces on Vercel.","/blog/how-to/vercel-headers","CSP on Vercel",[783,799],{"description":800,"href":801,"title":802},"Understanding Cross-Site Scripting attacks.","/blog/vulnerabilities/xss","XSS Vulnerability Explained",{"title":265,"searchDepth":804,"depth":804,"links":805},2,[806,807,808,809,819,825,831,838,839],{"id":42,"depth":804,"text":43},{"id":62,"depth":804,"text":63},{"id":78,"depth":804,"text":79},{"id":239,"depth":804,"text":240,"children":810},[811,813,814,815,816,817,818],{"id":248,"depth":812,"text":249},3,{"id":274,"depth":812,"text":275},{"id":290,"depth":812,"text":291},{"id":306,"depth":812,"text":307},{"id":343,"depth":812,"text":344},{"id":368,"depth":812,"text":369},{"id":404,"depth":812,"text":405},{"id":471,"depth":804,"text":472,"children":820},[821,822,823,824],{"id":475,"depth":812,"text":476},{"id":485,"depth":812,"text":486},{"id":501,"depth":812,"text":502},{"id":511,"depth":812,"text":512},{"id":521,"depth":804,"text":522,"children":826},[827,828,829,830],{"id":525,"depth":812,"text":526},{"id":544,"depth":812,"text":545},{"id":557,"depth":812,"text":558},{"id":567,"depth":812,"text":568},{"id":580,"depth":804,"text":581,"children":832},[833,834,835,836,837],{"id":584,"depth":812,"text":585},{"id":611,"depth":812,"text":612},{"id":641,"depth":812,"text":642},{"id":670,"depth":812,"text":671},{"id":702,"depth":812,"text":703},{"id":731,"depth":804,"text":732},{"id":774,"depth":804,"text":775},"how-to","2026-01-08","Complete guide to Content Security Policy setup. Learn CSP directives, implement nonces, configure reporting, and create policies for common frameworks. Includes starter templates.",false,"md",[846,848,850,852,854],{"question":739,"answer":847},"Content Security Policy is an HTTP header that tells browsers which sources of content are allowed to load on your page. It prevents XSS attacks by blocking unauthorized scripts, styles, images, and other resources from executing or loading.",{"question":745,"answer":849},"CSP blocks content that doesn't match your policy. Common issues: inline scripts blocked (need nonces or 'unsafe-inline'), third-party resources blocked (add their domains), or eval() calls blocked (need 'unsafe-eval'). Check browser console for specific violations.",{"question":751,"answer":851},"'unsafe-inline' significantly weakens CSP protection against XSS. Instead, use nonces or hashes for inline scripts. For styles, 'unsafe-inline' is often needed for CSS-in-JS libraries, but try to migrate to external stylesheets when possible.",{"question":757,"answer":853},"A nonce is a random, one-time-use value generated for each request. You add the nonce to your CSP header (script-src 'nonce-abc123') and to each inline script tag (nonce='abc123'). Only scripts with matching nonces execute, preventing injected scripts from running.",{"question":855,"answer":856},"What is the difference between CSP report-only and enforced mode?","Content-Security-Policy enforces the policy and blocks violations. Content-Security-Policy-Report-Only only reports violations without blocking. Start with report-only to identify issues, then switch to enforced once your policy is correct.","yellow",null,{},true,"Complete guide to CSP directives, nonces, reporting, and common policies for modern web apps.","/blog/how-to/csp-setup","[object Object]","HowTo",{"title":5,"description":842},{"loc":862},"blog/how-to/csp-setup",[],"summary_large_image","u7PpbcYVH_CY8fpNQkRBLeRBR_74s_cosMyyEr1ARks",1775843928914]