Search code examples
node.jsbootstrap-5helmet.js

Helmet middleware disable drop down from working and create an error in the console


Why when I add the helmet middleware to my app, the dropdown menus stops working and I get the following error in the console:

Refused to load the script 'https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

This is how I added helmet to my app:

const helmet = require('helmet');
...
app.use(helmet())

Solution

  • Helmet maintainer here.

    This is happening because of something called Content Security Policy, which Helmet sets by default. To solve your problem, you will need to configure Helmet's CSP.

    MDN has a good documentation about CSP which I would recommend reading for background. After that, take a look at Helmet's README to see how to configure its CSP component.

    To give some help specific to this question, let's take a look at one error you're seeing:

    Refused to load the script 'https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.
    

    This error is telling you that the script-src directive of your CSP does not allow JavaScript to load from cdn.jsdelivr.net, and so it was blocked.

    There are several ways to fix this:

    1. Update your CSP to allow JavaScript to load from this domain. You'd do something like this:

      app.use(
        helmet({
          contentSecurityPolicy: {
            useDefaults: true,
            directives: {
              "script-src": ["'self'", "cdn.jsdelivr.net"],
            },
          },
        })
      );
      
    2. Refactor your app to avoid loading JavaScript from that domain. Probably not possible, but it is an available solution.

    3. Disable CSP. This is the most dangerous option so I don't recommend it.

      app.use(
        helmet({
          contentSecurityPolicy: false,
        })
      );
      

    In summary: to solve your problem, you will need to tell Helmet to configure your CSP.