4

I have a gulp task that runs browsersync.

var options = {
        proxy :          'localhost:9000/html' ,
        port :           3000 ,
        files :          [
            config.root + config.srcPaths.htmlBundle ,
            config.htmlRoot + 'main.css' ,
            '!' + config.htmlRoot + '**/*.scss'
        ] ,
        injectChanges :  false ,
        logFileChanges : true ,
        logPrefix :      'broserSync ->' ,
        notify :         true ,
        reloadDelay :    1000
    };
browserSync( options );

browsersync detects changes and tries to inject them but chrome blocks it with this error:

Refused to connect to 'ws://localhost:3000/browser-sync/socket.io/?EIO=3&transport=websocket&sid=gOQQPSAc3RBJD2onAAAA' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.

Uncaught SecurityError: Failed to construct 'WebSocket': Refused to connect to 'ws://localhost:3000/browser-sync/socket.io/?EIO=3&transport=websocket&sid=gOQQPSAc3RBJD2onAAAA' because it violates the document's Content Security Policy.

How can i overcome this issue? Can i turn off the security policy?

Tomer
  • 17,787
  • 15
  • 78
  • 137

3 Answers3

7

Or you can add rules to your content security policy in the main html file (ex. index.html) to accept web socket connections from browser-sync. You can do it by adding ws://localhost:* to your default-src, for example like that:

<meta http-equiv="Content-Security-Policy"
      content="
        default-src 'self' ws://localhost:*">

You can also specify the exact browser-sync port like that:

<meta http-equiv="Content-Security-Policy"
      content="
        default-src 'self' ws://localhost:3000">

Just remember to remove this from policy before publishing to production servers!!

Maksymilian Majer
  • 2,956
  • 2
  • 29
  • 42
  • Yes, and more precisely, you can use the `connect-src` directive to restrict only to xhr, websockets and sse. – ngryman Jan 21 '16 at 12:42
  • this doesn't work in this time anymore. September 2019. – KD.S.T. Sep 17 '19 at 13:27
  • You might want to use the more specific directive `connect-src`. The `default-src` is just the fallback which is also shared by `font-src`, `script-src` etc. – scipilot Sep 18 '20 at 04:02
  • Also if you are using TLS, then it would be more like `wss://localhost:3001` , I noticed the extra S today. – scipilot Sep 18 '20 at 04:04
  • Oh sorry @ngryman I should have read your comment first! – scipilot Sep 18 '20 at 04:05
  • Does not work in Chromium browsers. No matter what is in the csp, even [this](https://stackoverflow.com/a/62057156/757201), the error remains. Browsersync does seem to work however – Jos Jun 24 '21 at 07:43
5

Not sure if it's the best solution, but what i ended up doing is to install a chrome plugin that disables the csp:

https://chrome.google.com/webstore/detail/disable-content-security/ieelmcmcagommplceebfedjlakkhpden

If anyone has a better solution i'll be glad to hear it.

Tomer
  • 17,787
  • 15
  • 78
  • 137
  • While this answer seems to be acceptable by the author, it is not the best option. Extension removes security errors and warnings from your development environment, so if you add some source that is not enabled by CSP you're risking of running into the problem much later. Answer by Maksymilian Majer is better. – sergeyski.com Nov 25 '18 at 21:04
  • this doesn't work with gulp 3.9 and react 16.9 (just some good info) – KD.S.T. Sep 17 '19 at 13:29
3

If the CSP is set in the html meta tag then a slightly less ugly solution is to have browser-sync disable this itself. Adding something like this to the browser-sync config should do the trick:

rewriteRules: [
  {
      match: /Content-Security-Policy/,
      fn: function (match) {
          return "DISABLED-Content-Security-Policy";
      }
  }
],

If you're really smart you could inject the correct CSP rules that permit browser-sync to do its stuff. Perhaps one diligent soul will end up writing a plugin to do just this?

Matthew
  • 10,361
  • 5
  • 42
  • 54
  • By far, this seems like the best solution. I use both browser-sync from the command line and gulp, and using a bs-config.js to do the rewrite seems like less of a hack and easier to maintain. –  Nov 16 '15 at 02:30
  • 2
    I liked this solution the best, however instead of disabling CSP altogether I used match/replace to update the rule. `rewriteRules: [ { match: "connect-src 'self'", replace: "connect-src ws: 'self'" } ]` – Cycododge Feb 21 '17 at 17:18
  • this doesn't work in this time anymore. September 2019. – KD.S.T. Sep 17 '19 at 13:24