global object in strict mode

# John J Barton (13 years ago)

Long ago this list had a subject:

How to retrieve the global object in strict mode? mail.mozilla.org/pipermail/es5-discuss/2011-February/003919.html

Roughly the conclusion was:

var global = ("global", eval)("this");

However Content Security Policy

dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html

bans 'eval', (as well as all similar forms) making this solution fail.

Is there a non-eval based solution?

jjb

# Andrea Giammarchi (13 years ago)

the non eval solution for ES3 is

var global = function(){return this}();

and not with eval ...

In ES5 usually window is not writable/configurable but enumerable so theoretically you can rely in the window object unless your code is not evaluated through eval inside a function with a window variable redefined.

# John J Barton (13 years ago)

Thanks!

I guess I should ended my question this way: ...and because developers want to write code that works in browsers and not, perhaps ES can have a solution that is not as silly as the ones we are using now.

jjb

# Brendan Eich (13 years ago)

John J Barton wrote:

Thanks!

I guess I should ended my question this way: ...and because developers want to write code that works in browsers and not, perhaps ES can have a solution that is not as silly as the ones we are using now.

I'm not sure what the problem is -- I read the old thread, and noticed the solution:

/var global = Function("return this")();/

This is good for any code mode, strict or non-strict. Does CSP ban Function as well as eval?

But really, what's wrong with the old chestnut of capturing the global early at top level?

/var global = this;/

and using that name, or passing its value around, as needed?

It's not as if one must be able to utter an expression deep in a function nest to get a global -- or as if there is any identifier that might not be shadowed. We are not going to add a special syntactic form for "the global". So I don't think the solutions available or "silly", or the problem is exactly what this thread makes it out to be.

But possibly I misunderstood the problem.

# Kris Kowal (13 years ago)

On Fri, Aug 24, 2012 at 10:41 AM, Brendan Eich <brendan at mozilla.org> wrote:

I'm not sure what the problem is -- I read the old thread, and noticed the solution: var global = Function("return this")(); This is good for any code mode, strict or non-strict. Does CSP ban Function as well as eval?

CSP does forbid the Function constructor, by the edict “Code will not be created from strings”.

www.w3.org/TR/CSP Section 4.2 “If unsafe-eval is not allowed…”

Kris Kowal

# Brendan Eich (13 years ago)

Kris Kowal wrote:

On Fri, Aug 24, 2012 at 10:41 AM, Brendan Eich<brendan at mozilla.org> wrote:

I'm not sure what the problem is -- I read the old thread, and noticed the solution: var global = Function("return this")(); This is good for any code mode, strict or non-strict. Does CSP ban Function as well as eval?

CSP does forbid the Function constructor, by the edict “Code will not be created from strings”.

www.w3.org/TR/CSP Section 4.2 “If unsafe-eval is not allowed…”

Sure, makes sense (I think I even knew that once -- have to catch up on CSP when I have some time, next millennium :-P).

Is it common to want an expression, usable in any context (non-strict, strict, CSP, deep in a function nest with potentially many names in scope, some of which might shadow globals), that evaluates to "the current global object"?

JS libraries do things like

(funciton (global) { // all the code here })(this);

and that works, as well as the brute force

var global = this;

approach. But one must take care not to shadow the name.

Could ES6 add a predefined global property named 'global', set to reference the global object? I suppose maybe - it would be writable or (to use WebIDL's term) [Replaceable]. We can't just make a const global, we will break extant code.

Is this global global important to standardize?

# Mark S. Miller (13 years ago)

On Fri, Aug 24, 2012 at 10:51 AM, Brendan Eich <brendan at mozilla.org> wrote:

Kris Kowal wrote:

On Fri, Aug 24, 2012 at 10:41 AM, Brendan Eich<brendan at mozilla.org> wrote:

I'm not sure what the problem is -- I read the old thread, and noticed the solution: var global = Function("return this")(); This is good for any code mode, strict or non-strict. Does CSP ban Function as well as eval?

CSP does forbid the Function constructor, by the edict “Code will not be created from strings”.

www.w3.org/TR/CSP Section 4.2 “If unsafe-eval is not allowed…”

Sure, makes sense (I think I even knew that once -- have to catch up on CSP when I have some time, next millennium :-P).

Is it common to want an expression, usable in any context (non-strict, strict, CSP, deep in a function nest with potentially many names in scope, some of which might shadow globals), that evaluates to "the current global object"?

JS libraries do things like

(funciton (global) { // all the code here })(this);

and that works, as well as the brute force

var global = this;

approach. But one must take care not to shadow the name.

Could ES6 add a predefined global property named 'global', set to reference the global object? I suppose maybe - it would be writable or (to use WebIDL's term) [Replaceable]. We can't just make a const global, we will break extant code.

Is this global global important to standardize?

It is important to not standardize. The global provides essentially the full authority provided by that frame. CSP restricts eval and Function presumably for some security reason ;). ES5/strict prevents ambient access to the global because it leads both to bad software engineering and to security holes. SES makes use of that inability to provide a virtualized global to untrusted code executing within the frame. SES virtualizes Function and eval at the same time, which prevents backdoor access to the real global.

# John J Barton (13 years ago)

On Fri, Aug 24, 2012 at 10:51 AM, Brendan Eich <brendan at mozilla.org> wrote:

Kris Kowal wrote:

On Fri, Aug 24, 2012 at 10:41 AM, Brendan Eich<brendan at mozilla.org> wrote:

I'm not sure what the problem is -- I read the old thread, and noticed the solution: var global = Function("return this")(); This is good for any code mode, strict or non-strict. Does CSP ban Function as well as eval?

CSP does forbid the Function constructor, by the edict “Code will not be created from strings”.

www.w3.org/TR/CSP Section 4.2 “If unsafe-eval is not allowed…”

Sure, makes sense (I think I even knew that once -- have to catch up on CSP when I have some time, next millennium :-P).

CSP creates another JS environment by banning certain JS features.

Is it common to want an expression, usable in any context (non-strict, strict, CSP, deep in a function nest with potentially many names in scope, some of which might shadow globals), that evaluates to "the current global object"?

I guess the purpose of "global" is to document dependency on the JS global objects but not on the rest of the global objects attached to |window|.

(To your earlier question about the 'problem', my problem is simply to use some else's JS code in a CSP environment. It uses the eval form. I need to convince them of an alternative. But it seems like this will be a common problem, hence my post).

JS libraries do things like

(funciton (global) { // all the code here })(this);

and that works, as well as the brute force

var global = this;

approach. But one must take care not to shadow the name.

Perhaps that is the reason for the funky construct, var global = ("global", eval)("this"); perfectionkills.com/global-eval-what-are-the-options

# Brendan Eich (13 years ago)

Mark S. Miller wrote:

On Fri, Aug 24, 2012 at 10:51 AM, Brendan Eich <brendan at mozilla.org <mailto:brendan at mozilla.org>> wrote:

Is this global global important to standardize?

It is important to not standardize.

Suits me! One fewer thing to standardize.

# David Bruant (13 years ago)

Le 24/08/2012 20:15, Mark S. Miller a écrit :

On Fri, Aug 24, 2012 at 10:51 AM, Brendan Eich <brendan at mozilla.org <mailto:brendan at mozilla.org>> wrote:

Kris Kowal wrote:

    On Fri, Aug 24, 2012 at 10:41 AM, Brendan
    Eich<brendan at mozilla.org <mailto:brendan at mozilla.org>>  wrote:

        I'm not sure what the problem is -- I read the old thread,
        and noticed the
        solution:
        var global = Function("return this")();
        This is good for any code mode, strict or non-strict. Does
        CSP ban Function
        as well as eval?


    CSP does forbid the Function constructor, by the edict "Code
    will not
    be created from strings".

    http://www.w3.org/TR/CSP/ Section 4.2 "If unsafe-eval is not
    allowed..."


Sure, makes sense (I think I even knew that once -- have to catch
up on CSP when I have some time, next millennium :-P).

Is it common to want an expression, usable in any context
(non-strict, strict, CSP, deep in a function nest with potentially
many names in scope, some of which might shadow globals), that
evaluates to "the current global object"?

JS libraries do things like

(funciton (global) {
  // all the code here
})(this);

and that works, as well as the brute force

var global = this;

approach. But one must take care not to shadow the name.

Could ES6 add a predefined global property named 'global', set to
reference the global object? I suppose maybe - it would be
writable or (to use WebIDL's term) [Replaceable]. We can't just
make a const global, we will break extant code.

Is this global global important to standardize?

It is important to not standardize. The global provides essentially the full authority provided by that frame. CSP restricts eval and Function presumably for some security reason ;). ES5/strict prevents ambient access to the global because it leads both to bad software engineering and to security holes. SES makes use of that inability to provide a virtualized global to untrusted code executing within the frame. SES virtualizes Function and eval at the same time, which prevents backdoor access to the real global.

Not saying that I'm in favor of a global global, but SES could provide a virtualized global when untrusted code asks for the free variable "global" as it certainly does with the "window" and "frames" variable.

When it'll be possible to have the virtualized global as a proxy, it will be possible to even dynamically replace accesses to the global object with the vitualized object regardless of how it's been aliased.

My point being that adding a global global does not increase the security hazard. I however agree it sort of sends the wrong message.

# Brendan Eich (13 years ago)

John J Barton wrote:

On Fri, Aug 24, 2012 at 10:51 AM, Brendan Eich<brendan at mozilla.org> wrote:

Kris Kowal wrote:

On Fri, Aug 24, 2012 at 10:41 AM, Brendan Eich<brendan at mozilla.org> wrote:

I'm not sure what the problem is -- I read the old thread, and noticed the solution: var global = Function("return this")(); This is good for any code mode, strict or non-strict. Does CSP ban Function as well as eval? CSP does forbid the Function constructor, by the edict “Code will not be created from strings”.

www.w3.org/TR/CSP Section 4.2 “If unsafe-eval is not allowed…” Sure, makes sense (I think I even knew that once -- have to catch up on CSP when I have some time, next millennium :-P).

CSP creates another JS environment by banning certain JS features.

Ya I know (Mozilla started CSP), I was just being slow there ;-).

Is it common to want an expression, usable in any context (non-strict, strict, CSP, deep in a function nest with potentially many names in scope, some of which might shadow globals), that evaluates to "the current global object"?

I guess the purpose of "global" is to document dependency on the JS global objects but not on the rest of the global objects attached to |window|.

Mark's point overrides. If someone needs the global, there's a capability in non-SES JS: it must be handled carefully, though. That's the non-silly part of the non-problem I was describing :-|.

(To your earlier question about the 'problem', my problem is simply to use some else's JS code in a CSP environment. It uses the eval form. I need to convince them of an alternative. But it seems like this will be a common problem, hence my post).

I'm not sure how common. Globals are considered harmful for good reason.

JS libraries do things like

(funciton (global) { // all the code here })(this);

and that works, as well as the brute force

var global = this;

approach. But one must take care not to shadow the name.

Perhaps that is the reason for the funky construct, var global = ("global", eval)("this"); perfectionkills.com/global-eval-what-are-the-options

That's for inside a function. The comma-expression eval callee is to force indirect eval, which evaluates global code.

That pattern does not help avoid shadowing of names, of course. Non-strict outer code could even shadow 'eval' and make that code do other than what's expected. My point about shadowing was not meant to encourage a shadow-proof name for the global object, though.

Really, if you need the global, you can save 'this' at top level in a var you create, or pass it down to a function call. I know this does not help local needs for "the global object", but I suspect those are rare and should be recast anyway (Mark's point).

# Aymeric Vitte (13 years ago)

We don't know what name has 'global' (ie var global=this, var window=this, etc)

This is what I tried to figure out here among others : gist.github.com/2995641 ("automatic" global.global=global, window.window=window), maybe impossible, unlikely, or whatever

I don't know well about this CSP proposal but it seems strange to me everytime something states that 'eval' is forbidden or stuff like this, a 'wrap' or equivalent would be better

Le 24/08/2012 19:51, Brendan Eich a écrit :

# Bill Frantz (13 years ago)

On 8/24/12 at 10:46, kris.kowal at cixar.com (Kris Kowal) wrote:

On Fri, Aug 24, 2012 at 10:41 AM, Brendan Eich <brendan at mozilla.org> wrote:

I'm not sure what the problem is -- I read the old thread, and noticed the solution: var global = Function("return this")(); This is good for any code mode, strict or non-strict. Does CSP ban Function as well as eval?

CSP does forbid the Function constructor, by the edict “Code will not be created from strings”.

www.w3.org/TR/CSP Section 4.2 “If unsafe-eval is not allowed…”

Of course you can't do this. One can always write an interpreter in Javascript and interpret any string as code.

What you can do is keep interpretation from using "forbidden" features by preventing them from being used by the interpreter, and therefore any language it is interpreting. You can not easily prevent such features from being used by strings being eval-ed.

Cheers - Bill


Bill Frantz | If the site is supported by | Periwinkle (408)356-8506 | ads, you are the product. | 16345 Englewood Ave www.pwpconsult.com | | Los Gatos, CA 95032

# Mark S. Miller (13 years ago)

On Sat, Aug 25, 2012 at 7:25 AM, Bill Frantz <frantz at pwpconsult.com> wrote:

On 8/24/12 at 10:46, kris.kowal at cixar.com (Kris Kowal) wrote:

On Fri, Aug 24, 2012 at 10:41 AM, Brendan Eich <brendan at mozilla.org>

wrote:

I'm not sure what the problem is -- I read the old thread, and noticed the solution: var global = Function("return this")(); This is good for any code mode, strict or non-strict. Does CSP ban Function as well as eval?

CSP does forbid the Function constructor, by the edict “Code will not be created from strings”.

www.w3.org/TR/CSP Section 4.2 “If unsafe-eval is not allowed…”

Of course you can't do this. One can always write an interpreter in Javascript and interpret any string as code.

What you can do is keep interpretation from using "forbidden" features by preventing them from being used by the interpreter, and therefore any language it is interpreting. You can not easily prevent such features from being used by strings being eval-ed.

Hi Bill, well put. This is precisely what the SES confining eval does -- it denies access by default to any object that can cause any externally visible effects. It therefore provides all the integrity that can be provided by denying access to eval, but it does so while still dynamically providing the full power of JS to compute computable functions, obviating the need to write such an eval in JS. SES accepts a different subset of JS than the eval-prohibiting CSP, and therefore breaks a different subset of existing programs. It would be interesting to measure which subsetting is more painful.