What are the correct steps to import the scripts?

That’s right, you should be using a nonce or a hash but not both. If you use just one do you get the same error?

Please see this document for more information:

In most cases, using the SHA hash should be the easiest to implement.

If you want to use a nonce, you can generate it uniquely and use it both in the CSP header and the client code.

Using the Basic Sample App as an example:

app.js
Generate a nonce

// generate a nonce for inlining scripts and styles
app.use((req, res, next) => {
    res.locals.cspNonce = crypto.randomBytes(16).toString('hex');
    next();
});

//...

const headers = {
    frameguard: {
        action: 'sameorigin',
    },
    hsts: {
        maxAge: 31536000,
    },
    referrerPolicy: 'same-origin',
    contentSecurityPolicy: {
        directives: {
            'default-src': 'self',
            styleSrc: [
                "'self'",
                (req, res) => `'nonce-${res.locals.cspNonce}'`,
            ],
            scriptSrc: [
                "'self'",
                (req, res) => `'nonce-${res.locals.cspNonce}'`,
            ],
            imgSrc: ["'self'", `https://${redirectHost}`],
            'connect-src': 'self',
            'base-uri': 'self',
            'form-action': 'self',
        },
    },
};

server/routes/index.js
Change the route to return the nonce you created

//...
        return res.render('index', {
            nonce: res.locals.cspNonce
            isZoom,
            title: `Hello ${name}`,
        });

server/views/index.pug
Use the variable in the client template

append scripts
    if isZoom
        script(nonce=nonce src='https://example.com/dep.js')
        script(type="module" src='/js/bundle.mjs')
        script(nomodule src='/js/bundle.js')

I hope that helps!

2 Likes