Skip to content

CSP unsafe-inline required to use? #616

Closed

Description

@lol768

Version

4.1.3

Browser and OS info

Firefox 59.0b8

Steps to reproduce

  • Read README
  • Attempt to use Vue dev tools on site with strict CSP headers
  • Check console for errors:

Content Security Policy: The page’s settings blocked the loading of a resource at self (“script-src”). Source: ;(function(e){let t={};if(e.hasOwnProper....
Page:1

Content Security Policy: The page’s settings blocked the loading of a resource at self (“script-src”). Source: ;(function(e){setTimeout(()=>{const n=do....
Page:1

Content Security Policy: The page’s settings blocked the loading of a resource at self (“script-src”). Source: ;(function(e){let n=null,t=0;const o={no....
Page:1

  • Re-read README.md hoping that requirement to inject scripts in this way is documented somewhere
  • Relax CSP headers to allow unsafe-inline
  • Vue devtools start working

What is expected?

  • Dev tools should operate without having to compromise on site security by allowing inline scripts
  • If this isn't technically possible, this incompatibility should be documented clearly in the README

What is actually happening?

  • Dev tools cannot detect running Vue instance

Activity

  1. Akryum commented on Feb 12, 2018

    @Akryum
    Member

    The devtools can't communicate with the webpage without injecting a script.

  2. lol768 commented on Feb 14, 2018

    @lol768
    Author

    Does it have to be inline? Can you reference a moz-extension script, or one that's externally hosted?

  3. chearon commented on Feb 15, 2018

    @chearon
    Contributor

    There's at least one extension developer who's gotten around CSP. This was a hard error to figure out for me, and disabling CSP locally isn't really ideal either. I haven't looked at how the extension communicates with Vue yet, but there might be a way...

  4. chearon commented on Feb 16, 2018

    @chearon
    Contributor

    Been playing around a bit with this and I've found a few ways to get the dev tools working with CSP enabled. The first two solutions require changes to vue-devtools:

    1. In hook.js and detector.js where the <script> elements are created, if it did a setAttribute('nonce', 'vue') then for dev mode people could add 'nonce-vue' to script-src. This would leave CSP on for everything else so you can still catch stray script tags before going on production huh, actually I think this issue is Firefox-only
    2. Firefox actually lets you evaluate stuff on the main window using window.eval(), so for that browser you could skip the createElement('script') entirely.
    3. If neither of these got merged or for those who need a solution now, you can just add the intializing code into to your development build. The function in hook.js goes before require('vue'), then add window.postMessage({devtoolsEnabled: true, vueDetected: true}, '*') right after. I might release an NPM module to make it easier.

    Would a PR for 1 and 2 be accepted?

  5. lol768 commented on Feb 20, 2018

    @lol768
    Author

    Hey @chearon!

    Appreciate you taking the time to look into this.

    There's at least one extension developer who's gotten around CSP

    Admittedly this is a creative solution, but I wouldn't say it's the nicest fix I've ever seen 😉

    if it did a setAttribute('nonce', 'vue') then for dev mode people could add 'nonce-vue' to script-src. This would leave CSP on for everything else so you can still catch stray script tags before going on production

    This isn't a bad approach. My only worry would be people leaving this on in production (and then it becomes a neat way for you to bypass CSP for your XSS payload!) -let's be honest, at least one person would probably do this so it feels too much like giving developers a shotgun to blow their own feet off with.

    Firefox actually lets you evaluate stuff on the main window using window.eval(), so for that browser you could skip the createElement('script') entirely.

    Interesting, and it seems like in Chrome the extensions aren't impacted by CSP either (which is in-line with how I'd expect extensions to be treated by the browser). This could be a nice workaround for Firefox.

    If neither of these got merged or for those who need a solution now, you can just add the intializing code into to your development build. The function in hook.js goes before require('vue'), then add window.postMessage({devtoolsEnabled: true, vueDetected: true}, '*') right after. I might release an NPM module to make it easier.

    Honestly, I don't understand why this wasn't the approach taken from the beginning: two separate builds, one dev build with the dev tools initialization code in and one prod build without it. Am I missing something obvious which would have prevented this from working? Why is injecting scripts into the page preferable? I'm pretty sure React took the same approach and I really don't understand why.

    I can't see that this would cause problems if the dev tools weren't there, it'd just be a message sent into the aether.

  6. chearon commented on Feb 20, 2018

    @chearon
    Contributor

    I think the post I linked to was solving something a little different actually.

    Interesting, and it seems like in Chrome the extensions aren't impacted by CSP either

    Yep. So this issue is entirely a Firefox compatibility thing (see #621 which fixes it, I've been using it).

    Honestly, I don't understand why this wasn't the approach taken from the beginning...Why is injecting scripts into the page preferable

    I dunno, maybe a Vue team member can answer that. It does seem cleaner to have the initialize code inside a dev build; it wouldn't have to detect Vue by checking every element after X seconds. All browsers do support content scripts behind CSP in one way or another though.

  7. Akryum commented on Feb 20, 2018

    @Akryum
    Member

    I think this is to support Vue.config.devtools = true. And also not to increase the size of the library in production.

  8. michalsnik commented on Mar 11, 2018

    @michalsnik
    Member

    Hey, as I wrote in #621 I don't think we can go around unsafe-inline with eval, because it would violate unsafe-eval option in CSP directive. The nonce that isn't automatically regenerated on each request totally introduces security vulnerability too.

    I see two possible solutions:

  9. self-assigned this
    on Mar 11, 2018
  10. lol768 commented on Mar 11, 2018

    @lol768
    Author

    And also not to increase the size of the library in production.

    Why can't there be two separate builds, or a separate script we include on the page which contains the hook (which then won't trip CSP)?

  11. 1 remaining item

  12. lol768 commented on Mar 11, 2018

    @lol768
    Author

    I hadn't tried that, @michalsnik - but it's an interesting solution. Presumably I'd only need to add localhost to my script-src and that'd be it on the CSP side?

  13. chearon commented on Mar 11, 2018

    @chearon
    Contributor

    Over here I mentioned that extensions don't violate CSP and that dev environment headers are kinda risky.

    Whitelist specific hash in CSP directives , it's unique for each string, and it's impossible to trick it, as any modification in source code (even white space) will result in different sha calculation. More informations here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src

    I also went down this route but if I understand right, we have to update the hash any time you guys make changes to those files right?

    What might solve your problem is remote vue/devtools.

    I'm glad there's several options, but all of them involve us doing something or changing the application in a way to make the extension work. That's kind of a bummer considering Chrome users don't have to do anything :(

  14. jbosse commented on Nov 8, 2018

    @jbosse
    Contributor

    I am actually getting a CSP error in Chrome as well, not for the script but for the inline styles needed for the hilighting components in the DOM.

    Chrome will also not allow the inline style even if the has is added to style-src header. 😢

    backend.js:1 Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'"

    I don't think this is easily addressed until CSP 3.0 establishes a mechanism for allowing it and the best solution I can see is to add a setting to the extension that would simply disable the feature so my console log isn't getting spammed with CSP errors.

  15. TheCycoONE commented on Jan 14, 2019

    @TheCycoONE

    In firefox I'm now getting: Content Security Policy: The page’s settings blocked the loading of a resource at eval (“script-src”). and the extension still isn't working when CSP is enabled (without unsafe-*)

  16. TheCycoONE commented on Jan 14, 2019

    @TheCycoONE

    https://bugzilla.mozilla.org/show_bug.cgi?id=1267027 is the relevant upstream bug. I've read it, but I'm not sure if there is content that is useful, or specifically what changed in Firefox 58.

    In particular they point to the 'contentScripts' API as a workaround.

  17. chearon commented on Jan 14, 2019

    @chearon
    Contributor

    You're right, when I take off unsafe-eval the extension no longer works. #621 only fixes unsafe-inline.

    Too bad for Firefox. It's pretty clear they're doing it wrong. Someone on that bugzilla issue said the react/redux devtools have the same problem, which is probably just causing more devs to switch to Chrome.

    contentScripts looks promising though. I'll support your PR! Or open one if I find the time.

  18. cawoodm commented on Apr 3, 2019

    @cawoodm

    Is it correct that Vue doesn't work with CSPs which don't allow unsafe-eval?
    https://codepen.io/cawoodm/pen/eopwGP

    That's a pity for Electron developers where we are warned about NOT allowing unsafe-eval.
    image

  19. Riplar commented on Jul 8, 2019

    @Riplar

    @cawoodm I have the exact same problem. Did you find a solution?

  20. jbosse commented on Jul 8, 2019

    @jbosse
    Contributor
  21. Riplar commented on Jul 8, 2019

    @Riplar

    I just found a working solution:

    new Vue({
      el: '#app',
      store,
      router,
      i18n,
      render: function(createElement) {
        return createElement(App);
      },
      components: {
        App
      },

    https://www.codementor.io/vuejsdevelopers/why-you-should-avoid-vue-js-dom-templates-c4chvgjlh

  22. rnicholus commented on Feb 11, 2020

    @rnicholus

    It seems this is still an issue, preventing any apps with reasonable CSPs from using vue-devtools in Firefox. Has anyone found a workaround, or have an idea about how to update this add-on to fix that?

  23. kir0ul commented on Mar 27, 2021

    @kir0ul

    I have the same problem as in thelounge/thelounge#3897, I get Vue.js not detected as well as a long list of messages like the following with Firefox 87.0 and Vue.js devtools 5.3.4:

    Content Security Policy: The page’s settings blocked the loading of a resource at http://localhost:8098/socket.io/?EIO=3&transport=polling&t=NXo1bfS (“connect-src”).
    
  24. locked and limited conversation to collaborators on Feb 10, 2022
  25. converted this issue into a discussion #1701 on Feb 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions