Trying to make the web-app safer and force myself to control better future additions (JS and CSS assets on different CDNs), I'm running Helmet plugin in my Fastify (same as Express) web-app.
If I deactivate all Helmet controls like the following:
fastify.register(helmet, false)
all works fine and all resources are loaded on client.
Then I tried to play (until exhaustion) with different configurations, nothing is working. The config and the browser error as the following:
{
// contentSecurityPolicy: false,
crossOriginResourcePolicy: { policy: 'same-site'},
contentSecurityPolicy: {
directives: {
...require("fastify-helmet").contentSecurityPolicy.getDefaultDirectives(),
"default-src": ["'self'"],
"style-src": ["'self'", "'unsafe-inline'", 'unpkg.com', 'cdn.jsdelivr.net',
'fonts.googleapis.com', 'use.fontawesome.com'],
"script-src": ["'self'", 'unpkg.com', "cdn.jsdelivr.net", "'unsafe-inline'"],
"img-src": ["'self'", "'data'", "*.tile.osm.org"],
"font-src": ["'self'", 'fonts.googleapis.com', 'fonts.gstatic.com', 'use.fontawesome.com']
},
},
};
Even setting
{ contentSecurityPolicy: false, crossOriginResourcePolicy: { policy: 'same-site'} }
with other variations of policy: same-origin, cross-origin none seems to work.
As you can see, I'm running on LOCALHOST too and I didn't test elsewhere.
tl;dr: disable the Cross-Origin-Embedder-Policy
header, enabled by default in Helmet v5.
{
crossOriginEmbedderPolicy: false,
// ...
}
Helmet maintainer here.
Helmet sets the the Cross-Origin-Embedder-Policy
HTTP response header to require-corp
.
Setting this header means that loading cross-origin resources (like an image from another resource) is trickier. For example, loading a cross-origin like this...
<img alt="My picture" src="https://example.com/image.png">
...won't work unless example.com
explicitly allows it, by setting some response headers of its own. Your browser will try to load example.com/image.png
, and if it's not explicitly allowed, your browser will drop the response.
To fix this, you can prevent Helmet from setting the Cross-Origin-Embedder-Policy
header, like this:
app.use(
helmet({
crossOriginEmbedderPolicy: false,
// ...
})
);
I made a small sample app you can use to play around with this.