Ecma262: Cross-platforms method to enumerate all globals?

Created on 20 Jun 2018  Â·  9Comments  Â·  Source: tc39/ecma262

I'm currently working on a project to allow sandboxed loading of scripts. The basic approach is to selectively declare "shadow" variables for defined globals and native types. The problem is I'm not sure how to do this in the most generic way across all platforms. My current naive attempt is essentially:

`

    var namespaces = [this];

    if (typeof global != "undefined") namespaces.push(global);

    if (typeof window != "undefined") namespaces.push(window);

    var globals = [

      "Array",

      "RegExp",

      "Symbol",

      "Object",

      "Number",

      "Boolean",

      "String",

      "Function",

      "Date",

      "Error",

      "Iterator",

      "JSON",

      "Math",

      "eval"

    ];

    for (var index = 0; index < namespaces.length; ++index)

      globals = globals.concat(Object.keys(namespaces[index]));

`
That seems to work okay so far, but it's just too easy for things to fall through the cracks. Is there a more generic method to do this that is guaranteed to catch all possible definitions?

question

All 9 comments

The globals are Object.getOwnPropertyNames(global) where global is Function(‘return this’)() or the equivalent. I’m not sure what you’re asking for.

Separately, if you’re looking into sandboxing, you may want to look into prior art: Caja and SES.

@ljharb Thank you so much, precisely what I was looking for! And yes, somewhat familiar with Caja and SES but this is more of a "safe eval" type of project. Hadn't found anything yet along those lines so I decided to take a stab at it myself. Anyhow, thanks again for the prompt, helpful response. Cheers!

Object.getOwnPropertyNames(global) is as close as you'll get I think, but it will only enumerate all _var_-scoped globals like var and function declarations, it will not enumerate lexical globals, so it won't catch let/const/class declarations in the global scope.

Whether or not that matters probably depends on the details of what you're doing, but it is worth mentioning at least.

@loganfsmyth True, but as far as this project goes I really just want to provide a mechanism to prevent scripts from accessing/modifying properties of native types and platform-specific globals. Thank you for pointing that out though, definitely worth noting and I'll be sure to mention that in the documentation nonetheless.

Closing; but we can continue discussing as needed.

I don't think this safety is possible without a frozen realm because the
caller can always get to certain globals.

[].__proto__.smoosh = ...

On Wed, 20 Jun 2018, 20:16 Sebastian Garth, notifications@github.com
wrote:

@loganfsmyth https://github.com/loganfsmyth True, but as far as this
project goes I really just want to provide a mechanism to prevent scripts
from accessing/modifying properties of native types and platform-specific
globals. Thank you for pointing that out though, definitely worth noting
and I'll be sure to mention that in the documentation nonetheless.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/tc39/ecma262/issues/1240#issuecomment-398864851, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AGni9dxvXoRvbKQQjr2MkCOAo6MqLjkFks5t-p94gaJpZM4UvUql
.

The source code for Caja/SES is here, it is well worth reading to get an understanding for many of the JS edge cases that permit sandbox escapes, the startSES.js file is an appropriate place to begin reading. The codebase is well-commented.

@robpalme Hmm, I can't seem to produce anything meaningful from that. Would you mind providing a working example?

EDIT: Also, in the above case would it be sufficient to simply call Object.freeze([].__proto__) ?

@IgnoredAmbience Thanks, I'll have a look at that!

Was this page helpful?
0 / 5 - 0 ratings