uProxy-p2p icon indicating copy to clipboard operation
uProxy-p2p copied to clipboard

UP-01-003 Worker-based Isolation does not prevent XHR & Sockets etc.

Open cure53 opened this issue 10 years ago • 9 comments

Note: This issue technically affects FreeDOM. Please move the issue if necessary.

Freedom.js uses Web workers to isolate freedom contexts from each other and prevent them from directly accessing the DOM, which seems to be intended as a security measure for isolating different modules. However, web workers are not designed to provide secure isolation of code; they are designed for running heavyweight tasks in the background, with no direct access to the DOM or the window resulting as a side effect.

Web workers can e.g. still use XMLHttpRequest to perform HTTP requests to their origin, which is the same as the origin of the website that started the worker, they can load scripts without muted errors, they can use IndexedDB and so on. In a typical web application, the ability to perform XHRs in the name of the application’s domain effectively gives the worker full access to the application. Similarly, in a chrome application, the worker is not able to use the chrome.* APIs, but it can still use XMLHttpRequest to talk to all origins that are whitelisted in the application manifest.

This issue could be mitigated by erasing all potentially harmful objects in the global scope of the worker, but that solution seems somewhat brittle. We recommend switching to frame-based isolation with sandboxing instead as frames are designed for security. The following list of objects should be considered for deactivation:

  • Worker
  • WebSocket
  • XMLHttpRequest
  • XMLHttpRequestUpload
  • importScripts

The code to deactivate the object should make use of ES5’s Object.defineProperty()/Object.defineProperties(). This is because of the browser specific behavior of language features such as delete. While simply deleting an object inside a worker suffices in Firefox, on Chrome and related browsers it has no effect. Our tests found the following code to be most efficient:

Object.defineProperties(this, {
    'XMLHttpRequest': {value: null, configurable: false},
    'XMLHttpRequestUpload': {value: null, configurable: false},
    'Worker': {value: null, configurable: false},
    'importScript': {value: null, configurable: false},
    'WebSocket': {value: null, configurable: false}
});

console.log(new XMLHttpRequest());
console.log(new XMLHttpRequestUpload());
console.log(new Worker());
console.log(importScript());
console.log(new WebSocket());

cure53 avatar Aug 31 '14 14:08 cure53

One issue with frames that makes us hesitant to use them, even with the sandbox attribute to limit communication is that the frame code often will run in the same event loop as the outer page, allowing for denial of service issues. Workers will definitely run in a separate event loop, which seems preferable.

willscott avatar Aug 31 '14 14:08 willscott

The attack surface for a sandbox Iframe is also significantly larger. There you have a full blown DOM, sometimes even visible to the user (contentEditable, resulting drag & drop attacks etc.). In the Worker, you can execute JavaScript - but no DOM calls. We should be able to fully mitigate XSS using sand-boxed Iframes. But DoS? Hard.

While we didn't manage to find a browser allowing to use a DOM inside a worker (e.g. by using XHR & XHR.responseType='document'), it does make sense to close that particular channel.

cure53 avatar Aug 31 '14 15:08 cure53

Freedom issue for this is here: https://github.com/freedomjs/freedom/issues/110

iislucas avatar Oct 08 '14 14:10 iislucas

More detailed updates in freedom issue, but the short of it is this is the tentative whitelist: https://docs.google.com/a/cs.washington.edu/spreadsheets/d/1kVAtIPgAeFBRtt7JbgTegT7nYg57JPl63Lt3S0Ac794/edit#gid=0

And there's a few commits that mask things not on the whitelist from the global scope of webworkers in freedom.

agallant avatar Oct 24 '14 16:10 agallant

Can we clarify when we expect these changes to be in FreedomJS? We don't believe fixing this issue should be blocking for the uProxy release to Chrome/Firefox web stores (it is marked P2 and doesn't pose a threat to uProxy users until we have untrusted freedom modules), and so we don't want to have to do extra work to move XHRs to a core provider this quarter. Will there be a way for some modules (e.g. freedom-social-facebook) to get permission to use XHRs directly? Or can this be added to freedom 0.7? Thanks

On Fri Oct 24 2014 at 12:29:09 PM soycode [email protected] wrote:

More detailed updates in freedom issue, but the short of it is this is the tentative whitelist:

https://docs.google.com/a/cs.washington.edu/spreadsheets/d/1kVAtIPgAeFBRtt7JbgTegT7nYg57JPl63Lt3S0Ac794/edit#gid=0

And there's a few commits that mask things not on the whitelist from the global scope of webworkers in freedom.

— Reply to this email directly or view it on GitHub https://github.com/uProxy/uproxy/issues/365#issuecomment-60412378.

dborkan avatar Oct 24 '14 16:10 dborkan

I have less information/opinion about timeline, but re: modules that need access I think it'd be best to wrap it in an interface where the permissions can be specified in the manifest.

EDIT - which is basically the "move XHRs to a core provider", so yeah, if the decision is "not this quarter" then I can sit on this for the time being. Having the whitelist spreadsheet out there is still a good thing as people can peruse and comment as desired.

agallant avatar Oct 24 '14 16:10 agallant

I'd suggest we focus on P1 issues this quarter, then we can all be excited about contributing stuff to the release. :fireworks:

But, yes, moving XHR to core provider is the right thing for freedom 0.7 / uproxy 2

iislucas avatar Oct 24 '14 22:10 iislucas

Ah, and yes, whitelist spreadsheet is really useful!

iislucas avatar Oct 24 '14 22:10 iislucas

I think it's valuable to develop a definitive API of what is available in a module as part of the design document explaining the security properties of freedom.js so that we can go to outside security auditors and be able to say: this is what the freedom.js library claims to do for the system.

The response we've gotten so far from 2 different external parties was that they weren't comfortable auditing freedom because there was no clear sense of what properties they were trying to verify that it actually maintained.

It looks like the only thing that is pending removal that's being used at the moment is XHRs, which are used only in freedom-social-facebook. Presumably the fix-up work there would be part of the removal task, since it is so localized.

willscott avatar Oct 25 '14 17:10 willscott