# New built-in: Sandbox

**URL:** <https://es.discourse.group/t/new-built-in-sandbox/552>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [November 18, 2020, 1:16am UTC](https://es.discourse.group/t/new-built-in-sandbox/552 "2020-11-18T01:16:42Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![K4rakara](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/k4rakara/32/508_2.png) [@K4rakara](https://es.discourse.group/u/K4rakara)\
**Post date:** [November 18, 2020, 1:16am UTC](https://es.discourse.group/t/new-built-in-sandbox/552/1 "2020-11-18T01:16:42Z")

</div>

We all know that JavaScripts `eval` is unsafe, yet alluring. Why not offer a safe alternative?

* * *

Currently, it is essentially impossible to (fully) restrict the values that `eval` can access.

This is one solution, but it can still be escaped with ease:

```javascript

//"use strict"; You can't even use strict mode with this...

function safeishEval(code) {
  var scope = Object.create(null);
  var obscurer = {};
  for (const key in this)
    obscurer[key] = undefined;
  for (const key in self)
    obscurer[key] = undefined;
  for (const key in window)
    obscurer[key] = undefined;
  with (obscurer) {
    var isolated = function(code) {
      return eval(code);
    };
  }
  return isolated.call(scope, code);
}

safeishEval("1 + 2"); // => 3
// Somehow still logs "Hello world!"???
safeishEval("console.log('Hello world!')");
// Works, but doesn't have access to globals.
safeishEval("eval('console.log(\"Hello world!\")')");
// Function.prototype.constructor is accessible...
safeishEval("console.log(Function.prototype.constructor('console.log(\"Hello world\")')())");
// ... completely invalidating the safety of this "sandbox" 
safeishEval("Function.prototype.constructor('console.log(window)')()");

```

* * *

I would like to propose the following API:

```javascript

let mySensitiveValue = "something sensitive";
let myTypicalValue = "something typical";

new Sandbox(console, myTypicalValue)
  .eval(`console.log("Inside of the sandbox!");
    myTypicalValue += ", something typical";`
    // This should fail.
    + `try { mySensitiveValue += "... PWND!!!" }
    catch(err) {}`);

assert(mySensitiveValue === "something sensitive");
assert(myTypicalValue === "something typical, something typical");

```

The constructor exposes values to the `Sandbox`. In theory, you wouldn't even need to pass a name for each value, as `Sandbox` would need to be implemented in the JavaScript runtime itself, which should know the name of variables. Prototypes on exposed values should be "linked" to the prototypes used by the sandbox, as a protective measure.

The `eval` method evaluates code inside of the `Sandbox`, returning a value, just like vanilla `eval`.

* * *

But why should this be part of JavaScript itself, rather than a part of Browsers and/or NodeJS?

By making something like this part of the ECMAScript standard, it ensures that there is one singular sandbox that is tried and tested throughout all JavaScript runtimes.

In other words, by making this part of the ECMAScript standard, you effectively ensure that any potential security oversights are caught before the final version makes it into browsers.

* * *

I'd be foolish to not acknowledge the possible downsides of this API, so I'll go over them here:

- If a security _oversight_ is discovered in the sandbox after its launched, you have a zero day in the ECMAScript standard itself.
- If a security breach is discovered in the sandbox after its launched, you have a zero day in the affected browsers and/or runtimes.
- Impossible to polyfill.

* * *

I'd love to hear feedback regarding this.

Cheers!

---

<div class="post-metadata">

**Author:** ![jun-sheaf](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jun-sheaf/32/505_2.png) [@jun-sheaf](https://es.discourse.group/u/jun-sheaf)\
**Post date:** [November 19, 2020, 11:26pm UTC](https://es.discourse.group/t/new-built-in-sandbox/552/2 "2020-11-19T23:26:17Z")

</div>

Seems you don’t know what eval can truly do:

> **[JSFuck - Write any JavaScript with 6 Characters: \[\]()!+](http://www.jsfuck.com/)**

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [November 23, 2020, 3:00am UTC](https://es.discourse.group/t/new-built-in-sandbox/552/3 "2020-11-23T03:00:00Z")

</div>

You may want to look at [https://github.com/tc39/proposal-realms](https://github.com/tc39/proposal-realms) - this does exactly what you're looking for and more.

---

<div class="post-metadata">

**Author:** ![K4rakara](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/k4rakara/32/508_2.png) [@K4rakara](https://es.discourse.group/u/K4rakara)\
**Post date:** [November 25, 2020, 3:29pm UTC](https://es.discourse.group/t/new-built-in-sandbox/552/4 "2020-11-25T15:29:58Z")

</div>

Oh god, I forgot about that nightmare... Sometimes JS makes my head hurt.

---

<div class="post-metadata">

**Author:** ![K4rakara](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/k4rakara/32/508_2.png) [@K4rakara](https://es.discourse.group/u/K4rakara)\
**Post date:** [November 25, 2020, 3:31pm UTC](https://es.discourse.group/t/new-built-in-sandbox/552/5 "2020-11-25T15:31:29Z")

</div>

Thank you! This is exactly what I'm looking for! I know its gonna take a few years, but this will be amazing once it lands! (Stage 2 means its most likely going to be included, right?)

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [December 3, 2020, 11:10am UTC](https://es.discourse.group/t/new-built-in-sandbox/552/6 "2020-12-03T11:10:19Z")

</div>

> [@K4rakara](#):
>
> (Stage 2 means its most likely going to be included, right?)

Not necessarily - lots of things change shape at stage 2. It really depends on the feature.

This one in particular is likely to become a thing in some form or another simply due to the massive need for it in many different problem domains, though. (Google's SES needs practically the full power of that proposal, not just the execution side of it.)
