Eval, literal eval, safe eval

Thaddee Tyl thaddee.tyl at gmail.com
Sat Nov 29 16:41:24 PST 2014

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