Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove use of unsafe-eval #269

Closed
lidel opened this issue Jul 27, 2017 · 32 comments
Closed

Remove use of unsafe-eval #269

lidel opened this issue Jul 27, 2017 · 32 comments
Labels
help wanted Seeking public contribution on this issue kind/bug A bug in existing code (including security flaws) topic/security Work related to security
Milestone

Comments

@lidel
Copy link
Member

lidel commented Jul 27, 2017

We allowed unsafe-eval in browser extension because browserified bundle ipfs-api.min.js relies on eval. Unfortunately Mozilla does not accept extensions with unsafe-eval:

The use of 'unsafe-eval' is not allowed in the manifest.json's CSP as it can cause major security issues. [feedback from review]

[..] extensions with 'unsafe-eval', 'unsafe-inline', remote script, or remote sources in their CSP are not allowed for extensions listed on addons.mozilla.org due to major security issues. [MDN]

We need to address it somehow.

Any ideas @ipfs/javascript-team?
Is it possible to create own bundle without eval?
We can start using webpack if needed.

@lidel lidel added kind/bug A bug in existing code (including security flaws) help wanted Seeking public contribution on this issue topic/security Work related to security labels Jul 27, 2017
@lidel lidel added this to the v2.0.0 milestone Jul 27, 2017
@lidel lidel mentioned this issue Jul 27, 2017
9 tasks
@styfle
Copy link

styfle commented Jul 28, 2017

Can you link to the code that is doing the eval? And what is it evaluating?

@daviddias
Copy link
Member

searching for eval on the min file reveals that is something that Webpack injects as part of its bundling:

image

Which gets in because of the script loader webpack/webpack#4899

Investigating how to disable it (it's not actually present in our config file https://github.com/ipfs/aegir/blob/master/config/webpack.js)

@lidel
Copy link
Member Author

lidel commented Aug 13, 2017

FYSA we need to resolve this two-three weeks before Firefox 57 is released, otherwise users will be left dry without working browser extension :(

@daviddias
Copy link
Member

I believe we used the script-loader in the past due to our usage of node-forge which we don't use anymore.

@dignifiedquire sounds like the removal of script-loader can be one of the features for aegir@next? What do you say?

@lidel lidel mentioned this issue Aug 15, 2017
7 tasks
@dignifiedquire
Copy link
Member

I do not think the issue is the script-loader, I searched through all deps and it does not get installed and still eval is present in the built file.

@dignifiedquire
Copy link
Member

I believe I found the offender. The shim for vm relies on eval, and it seems this is used in the dependency asn1.

@dignifiedquire
Copy link
Member

dignifiedquire commented Aug 15, 2017

@daviddias
Copy link
Member

Need to think more about this, but I'm guessing that we can get rid of this https://github.com/substack/vm-browserify/blob/master/index.js#L105

@dignifiedquire
Copy link
Member

Looking at this PR it seems that things should work, it will try to use the eval and fail due to csp but still work. @lidel is the issue that any warning with eval will be rejected, or did you actually experienced failures because of the csp restrictions?

@lidel
Copy link
Member Author

lidel commented Aug 16, 2017

Mozilla rejected our submission due to unsafe-eval in our CSP:

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'; child-src 'self';",

They may not care if eval is in minified file as long as unsafe-eval is removed from CSP.

Which I can't do because ipfs-api (v14.0.4) does not work in WebExtension context without it.

@dignifiedquire It fails to load under both Firefox and Chrome:

2017-08-16-170832_826x160_scrot

2017-08-15-154938_924x286_scrot

@dignifiedquire
Copy link
Member

@lidel @diasdavid I have an experimental build which should improve things, could you try this out and let me know if it helps? (based on master if js-ipfs-api)
dist.zip

@lidel
Copy link
Member Author

lidel commented Aug 24, 2017

@dignifiedquire I replaced ipfs-api.min.js with index.js from your .zip and retested under Chrome/Firefox, both still fail due to CSP:

2017-08-25-005311_690x306_scrot

Seems that src String causes Function.apply to fail due to CSP:

2017-08-25-005424_525x239_scrot

@daviddias
Copy link
Member

@lidel you never had issues with connect-src on the CSP since you always dial to a localhost node, right?

If we were to try #248, we would need to figure out connect-src as it would block dials to WebSocket nodes.

@lidel
Copy link
Member Author

lidel commented Aug 28, 2017

@diasdavid correct, localhost and HTTP-only (no WSS), so there were no issues as long unsafe-eval is added.

@daviddias
Copy link
Member

@lidel @dignifiedquire what's the status here, any other ideas?

@lidel
Copy link
Member Author

lidel commented Sep 2, 2017

No good ideas on my end, just status update:

Firefox release is blocked due to unsafe-eval in manifest.json/content_security_policy
The eval seems to be required by both js-ipfs-api and is-ipfs. Both are built by AEgir.

The best case would be to find an upstream fix: the problem is not limited to this extension, as you've seen in ipfs-inactive/browser-laptop#1 (review) use of eval always causes weird looks. If we could remove its use completely, that would solve us headache across all projects.

There is a possibility we could find a workaround and sandbox eval, somehow.
I did some research at https://discourse.mozilla.org/c/add-ons, but found no working solution.
I've seen some iframe-based sandboxing attempts, but as far I can read into them, they address different issues and still require unsafe-eval and/or unsafe-inline.

@dignifiedquire
Copy link
Member

Update: Found out the Function.apply is from generator-function, which is a dependency of https://github.com/mafintosh/protocol-buffers which we use for protobuf support. Currently working on removing the use of that library.

@dignifiedquire
Copy link
Member

Step 1: ipfs/js-ipfs-unixfs#18

@dignifiedquire
Copy link
Member

dignifiedquire commented Sep 4, 2017

Step 2: ipld/js-ipld-dag-pb#39

@dignifiedquire
Copy link
Member

Step 3: libp2p/js-libp2p-crypto#107

@dignifiedquire
Copy link
Member

@lidel build without protocol-buffers lib and no Function.apply dist 2.zip. Want to give it another spin?

@lidel
Copy link
Member Author

lidel commented Sep 5, 2017

@dignifiedquire this version works without unsafe-eval in manifest.json, extension loaded and functionality seems to work fine 👍 🎉

FYI there was one CSP error:

2017-09-05-072907_722x138_scrot

it was triggered by this line of dist/index.js:

var mod = eval("quire".replace(/^/,"re"))(moduleName); // eslint-disable-line no-eval

but from what I was able to check it does not impact anything we use in browser extension.

As long as we don't have unsafe-eval in manifest.json it should pass the review at Mozilla, but if we can eliminate CSP errors from Browser Console completely, that would be even better.

Is it technically possible?

@dignifiedquire
Copy link
Member

Great to hear that @lidel. That eval is coming from our new protobuf library: protobufjs/protobuf.js#593 but should hopefully resolved soonish.

@dignifiedquire
Copy link
Member

@lidel latest release of js-ipfs-api should be free of eval, hopefully. Please give it another try :)

@lidel
Copy link
Member Author

lidel commented Sep 7, 2017

@dignifiedquire The latest one at npmjs.com is ipfs-api@14.3.3 and it still produces error due to Function.apply. I re-tested version from dist 2.zip and it still works fine.

I guess either you did not publish the latest version yet or there is some kind of regression since dist 2.zip

@daviddias
Copy link
Member

@lidel I was lucky with js-ipfs, you might have to do a fresh npm install and fresh npm run build with ipfs-api.

@lidel
Copy link
Member Author

lidel commented Sep 7, 2017

Just to eliminate possibility of me going insane 🙃

Does:

curl -s https://unpkg.com/ipfs-api@14.3.3/dist/index.js | grep -B 10 Function.apply 

return:

var src = 'return ('+line.toString()+')'

    var keys = Object.keys(scope || {}).map(function(key) {
      return key
    })

    var vals = keys.map(function(key) {
      return scope[key]
    })

    return Function.apply(null, keys.concat(src)).apply(null, vals)

on your boxes as well?

@dignifiedquire
Copy link
Member

Seems something went wrong in the release, unpkg version shows Function.apply but when I build on master with fresh deps it the apply is gone

@daviddias
Copy link
Member

One more time 🎶

image

@lidel
Copy link
Member Author

lidel commented Sep 7, 2017

ipfs-api@14.3.4 works indeed! 🚀

lidel added a commit that referenced this issue Sep 7, 2017
@dignifiedquire
Copy link
Member

ipfs-api@14.3.4 works indeed! 🚀

AWESOME 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Seeking public contribution on this issue kind/bug A bug in existing code (including security flaws) topic/security Work related to security
Projects
None yet
Development

No branches or pull requests

5 participants