KrakenJS Helmet CSP script-src directive default value
0 reputation · 31 Dec 2024, 04:03 UTC
0 reputation · 31 Dec 2024, 04:03 UTC
KrakenJS includes the Helmet middleware to automatically apply a Content Security Policy header. By default, the injected CSP omits a script-src directive, which permits all scripts unless the developer adds one explicitly. The goal is to determine whether KrakenJS should supply a default script-src value that balances security with developer ergonomics.
Constraints include avoiding breakage of legitimate inline scripts or third‑party widgets, accounting for browsers that do not support the strict-dynamic keyword, and limiting CSP violation report noise. The unresolved decision is whether to bake in a default such as 'self' strict-dynamic (with a fallback nonce or hash) or to leave the directive optional and rely on explicit configuration.
Should KrakenJS enable a default script-src that includes 'self' and strict-dynamic? How should the framework handle browsers lacking strict-dynamic support? What fallback mechanism, if any, should be provided to maintain security without generating excessive violation reports?
No — KrakenJS should not bake in a default script-src 'self' strict-dynamic. A strict-dynamic default only works when every entry-point script carries a nonce or hash, and KrakenJS has no templating pipeline that guarantees that. Shipping it as a default would break inline scripts, event handlers, and third-party widgets on first deploy. The right default is to leave script-src explicit, but ship a documented, opt-in policy pattern with a nonce-based fallback for older browsers.
Confirmed behavior of the pieces: strict-dynamic is ignored by browsers that don't support it (IE11, Safari before 14, older mobile browsers); those browsers fall back to the other sources listed in script-src. Modern browsers (Chrome 52+, Firefox 52+, Safari 14+) honor it and ignore host allowlists like 'self' in favor of trust propagated from a nonced script.
Likely, but verify in your install: KrakenJS has been effectively unmaintained since ~2018, and its bundled Helmet version predates Helmet v4's CSP-by-default behavior. Depending on the pinned Helmet version, your app may emit no CSP at all or a minimal one. Check before assuming anything:
npm list helmet\ncurl -sI https://your-app.example/ | grep -i content-security-policyThe standard compatible policy pairs a nonce with strict-dynamic:
script-src 'self' 'nonce-{per-request-random}' 'strict-dynamic'Modern browsers use the nonce on the bootstrap script and strict-dynamic to trust scripts it loads. Legacy browsers ignore strict-dynamic and execute only scripts carrying the valid nonce. 'self' acts as the legacy fallback for externally hosted first-party scripts; in strict-dynamic browsers it is ignored, so it costs nothing to include.
'unsafe-inline' breaks them immediately. This is the core reason it can't be a framework default.helmet.contentSecurityPolicy({\n reportOnly: true,\n directives: { scriptSrc: [\"'self'\", \"'nonce-...'\", \"'strict-dynamic'\"] }\n})Collect reports for one to two weeks, fix nonce gaps, then enforce. Ensure your report endpoint can handle volume or sample reports.Given KrakenJS's maintenance status, a baked-in default would have to work unattended for years across unknown applications — strict-dynamic fails that test. Provide the nonce + 'self' + strict-dynamic pattern as documented configuration, with report-only as the migration path. If your Helmet version turns out to be v3-era (no default CSP), the first step is simply enabling CSP explicitly at all.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.