Open
Description
Duplicate of github/secure_headers#348 but for helmet.
tl;dr Helmet sets upgrade-insecure-requests
header by default. This is fine, but Safari honours that header even if the website is being served over HTTP, which means that if I'm doing local web development, assets (styles, scripts etc.) get upgraded to HTTPS and don't get loaded.
This behaviour is quite hard to reason about—I've encountered it a few times before and only just (with the help of this Stack Overflow thread) figured out why it's happening.
The current workaround is to put some branching in the consumer layer:
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: [
"'self'",
(req, res) => `'nonce-${res.locals.cspNonce}'`
],
imgSrc: ["'self'"],
connectSrc: ["'self'"],
...(process.env.NODE_ENV === 'development' && {
upgradeInsecureRequests: null
})
}
})
)