Eval, literal eval, safe eval

Michał Wadas michalwadas at gmail.com
Sat Nov 29 17:18:14 PST 2014


This "library" (localeval) is almost useless and potentially
dangerous. There are thousands ways to break it's encapsulation and
attacker will use all of them.

localeval('('+function a(){
Function('this.a = 3')()
}+'())');
window.a; // 3


localeval('('+function a(){
this.a = 5
}+'())')
window.a; // 5

localeval('('+function a(){
({}).constructor.getOwnPropertyNames = function(){return []}
}+'())')
// Oh, it do not return globals to their natural state.

Possible ways to attack and break sandbox:
- getters/setters
- setTimeout and any asynchronous function
- forcing document reload or something like that
- throwing error (possibly with getter/setter)

Even worker implementation can do potentially dangerous actions like
retrieving data from site using XHR and then transmitting it over web
socket to attacker.

2014-11-30 1:41 GMT+01:00 Thaddee Tyl <thaddee.tyl at gmail.com>:
> On Sun, Nov 23, 2014 at 12:38 PM, Florian Bösch <pyalot at gmail.com> wrote:
>> Btw. you can do a sort of sandboxed eval today by overriding all names found
>> in window. There are some caveats however. The so sandboxed code can still
>> access (and change) object internals, such as
>> "mystring".constructor.prototype.asdf = function(){ console.log("gotcha");
>> }.
>
> You can do a lot more. You can prevent the issues you point out (and
> many others) by mocking all built-in object's prototypes that you want
> to feed the sandbox (so that modifications are actually performed on a
> throwaway prototype), and by removing all new properties that weren't
> there before and replacing those that were there before.
>
> I have an implementation of such a sandbox in ES5.1
> [here](https://github.com/espadrine/localeval), and a testing ground
> [there][localeval website].
> It does use eval(). And Function(). No Realm creation.
>
> For all purposes, it is a safe eval. I really wish that Chrome would
> use it in their DevTools; I broke them so many times while writing
> this library that I have lost count. They actually use no sandbox at
> all in their [js console].
>
> [localeval website]: (https://espadrine.github.io/localeval)
> [source]: https://github.com/espadrine/localeval
> [js console]: http://isawsomecode.tumblr.com/post/31418387725/making-the-js-console-intuitive
>
>> A sandboxes primary purpose isn't just to restrict access to global symbols,
>> it's also to prevent it from corrupting the surrounding codes internals. One
>> way to do that of course would be to have the so sandboxed code run in total
>> isolation on a separate VM instance, however there's some issues with that
>> too.
>>
>> It would often be the case that you'd want to provide an interface to the
>> sandboxed code. So sandboxing alone isn't quite sufficient, you'd also need
>> to have a suitable API/syntax to describe interfaces, safe to pass to the
>> sandboxed code, such that the sanboxed code cannot corrupt any piece of
>> those interfaces.
>
> Most of that is (laborious but) easy. The thorny bit in localeval is
> passing values to the sandbox. While it obviously works in the version
> without a timeout (although infinite loops aren't protected against),
> the version with a timeout, which relies on web workers (or processes
> in node), doesn't pass non-JSON-serializable values fine.


More information about the es-discuss mailing list