6

When I start my express app the browser gives me this error:

Refused to load the script 'http://localhost:1337/main.js' because it violates
the following Content Security Policy directive: "script-src unsafe-eval".
Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

In my index.js file I have set helmet up like so:

// Set Content Security Policies
const scriptSources = ["'self'", "'unsafe-inline'", "'unsafe-eval'"];
const styleSources = ["'self'", "'unsafe-inline'"];
const connectSources = ["'self'"];

app.use(
  helmet.contentSecurityPolicy({
    defaultSrc: ["'self'"],
    scriptSrc: scriptSources,
    scriptSrcElem: scriptSources,
    styleSrc: styleSources,
    connectSrc: connectSources,
    reportUri: '/report-violation',
    reportOnly: false,
    safari5: false  
  })
);
app.use(helmet({
  contentSecurityPolicy: false,
}));

and my index.html is loading in the .js file like this:

<script type="module" src="./main.js"></script>

Here is my GitHub Repo: https://github.com/jgonzales394/fsn.pw

jgonzales394
  • 99
  • 1
  • 6

3 Answers3

3

Helmet maintainer here. This is happening because your directives need to be nested under a directives property.

For example:

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: scriptSources,
      // ...
    },
  })
)
Evan Hahn
  • 12,147
  • 9
  • 41
  • 59
  • Added under directives and now i get this output from the terminal: https://pastebin.com/i2V1uPdY – jgonzales394 Nov 10 '20 at 17:11
  • This is because one of your directives is not iterable (in other words, it's not an array). Are all of the directive values arrays? Should some of the options be moved to the top level instead of under the `directives` key? – Evan Hahn Nov 14 '20 at 16:02
  • Ok so I setup csp like this https://pastebin.com/rjtQwjev and I'm still getting unsafe-eval is not allowed. When I do a get request using insomnia the header are set correct, as shown in this screenshot https://i.gyazo.com/212480ebd462f331c711d01924478f6a.png – jgonzales394 Nov 14 '20 at 23:49
1

Ok so I managed to get it working correctly. Helmet is allowing me to set my CSP this way:

app.use(
  helmet.contentSecurityPolicy({
    defaultSrc: ["'self'"],
    scriptSrc: scriptSources,
    scriptSrcElem: scriptSources,
    styleSrc: styleSources,
    connectSrc: connectSources,
    reportUri: '/report-violation',
    reportOnly: false,
    safari5: false  
  })
);

So my main.js file is a vue app and I had it written like this before:

import * as Vue from './src/vue.esm-browser.js';

const App = Vue.createApp({
  data() {
    return {
      slug,
      url
    }
  },
  methods: {
    createUrl() {
      console.log(this.slug, this.url);
    }
  }
}).mount('#app');

I rewrote the code like this:

import { createApp, ref } from './src/vue.esm-browser.js';

const slug = ref('');
const url = ref('');

createApp({
 setup() {
   const createUrl = () => {
     console.log(slug.value, url.value);
   };

   return {
     slug,
     url,
     createUrl
   };
 }
}).mount('#app');

and in my html file is was able to call createUrl without invoking it.

jgonzales394
  • 99
  • 1
  • 6
  • well this seemed to work for a minute. It was reverted back to this: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'". – jgonzales394 Nov 11 '20 at 19:54
0

Ok, so I had a similar issue. This was resolved when I nest the directive but not the report to as such

app.use(helmet({
    contentSecurityPolicy: {
        directives: {
          "script-src":['self',"http://localhost:3000/"],
        },
        reportOnly:true
      },
}))
Tyler2P
  • 2,324
  • 26
  • 22
  • 31