Fixing inline-script CSP errors¶
Barbacana injects a strict Content-Security-Policy by default:
default-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests
default-src 'self' blocks every inline <script> block, every inline event handler (onclick="…"), every <style> block, every javascript: URL, and every external script not served from the page's own origin. That is intentional — inline scripts are the primary vector for stored XSS, and CSP is the most effective mitigation.
If your app relies on inline scripts (server-rendered templates, legacy code, third-party widgets), the CSP must be loosened — but not by adding 'unsafe-inline' everywhere. Try the options below in order.
Symptoms¶
The page renders but JavaScript doesn't run, or specific widgets stay blank. The browser Console shows:
Refused to execute inline script because it violates the following
Content Security Policy directive: "default-src 'self'".
Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce
('nonce-...') is required to enable inline execution.
Other variants you may see:
Refused to apply inline style …— same issue,style-srcdirective.Refused to load the script 'https://cdn.example.com/foo.js' …— external script not inscript-src.Refused to load the image 'data:image/png;base64,…' …—data:URL not inimg-src.
The audit log shows nothing — CSP is enforced by the browser, not by Barbacana's request inspection.
Diagnose¶
- Open Developer Tools → Console and read the full CSP error. It tells you:
- which directive blocked it (
script-src,style-src,img-src, …), - the source it tried to load (
inline, an external URL, adata:URL, …), - and the exact CSP value Barbacana sent.
- which directive blocked it (
- Decide the source category:
- Inline
<script>or inline event handler → option 1, 2, or 3 below. - External script from another origin → add the origin to
script-src. - Inline style (
<style>block,style="…"attribute) → same options applied tostyle-src. - Image from
data:URL → adddata:toimg-src.
- Inline
Option 1 — Move scripts to external files (best)¶
If you control the application, this is the most secure outcome — no CSP changes needed at all.
- Move every
<script>…</script>block to a separate.jsfile served from the same origin. - Replace inline event handlers (
onclick="doThing()") withaddEventListenerin those files. - Move inline styles to external CSS files.
Modern build tools (Vite, webpack, esbuild) emit external bundles by default — most refactoring is a question of stripping inline blocks from server-rendered HTML templates.
Option 2 — Allow specific inline scripts via nonce or hash¶
If you can modify the HTML but can't avoid inline scripts (server-rendered apps), allow them by nonce or hash instead of opening the entire 'unsafe-inline' door.
Nonce approach. The application generates a random per-response nonce, adds it to every inline script tag (<script nonce="abc123">…</script>), and reflects it in the CSP it sends. Barbacana doesn't generate the nonce — your application does. To let the upstream's CSP through unchanged on a route, disable Barbacana's CSP injection:
Your application is now responsible for sending a correct CSP on every response from that route.
Hash approach. For static inline blocks, compute the SHA-256 of the script body (the browser usually prints the expected hash directly in the console error) and inject a custom CSP:
routes:
- upstream: http://app:8000
response_headers:
preset: moderate
inject:
header-csp: "default-src 'self'; script-src 'self' 'sha256-AbC...='"
Option 3 — Allow 'unsafe-inline' (last resort)¶
Only do this if the app is internal, the threat model accepts the trade-off, or you're in a temporary unblock-and-fix-later situation:
routes:
- upstream: http://app:8000
response_headers:
preset: moderate
inject:
header-csp: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
This disables CSP-based XSS protection for inline scripts on that route. Scope it to the specific route that needs it; never apply it globally.
Allowing an external script source¶
If the error names an external URL rather than inline, list that origin in script-src:
The same pattern works for style-src, img-src, connect-src, font-src, etc.
Verify¶
After every CSP change:
- Hard-refresh the page (DevTools open → right-click reload → Empty Cache and Hard Reload). CSPs are aggressively cached.
- Confirm the Console is clear of CSP errors.
- In the Network tab, click the document request and check that the response carries your custom
Content-Security-Policyheader — not the default.
Related¶
- Security headers reference — full list of headers Barbacana injects and how presets work.
- Protection catalog — every
header-*key you caninjectordisable.