是否可以在严格的代码中更改标识符`eval`的值?

时间:2012-09-27 17:58:17

标签: javascript theory

严格模式提供的一个保证是在严格的函数代码中,标识符arguments总是引用该函数的Arguments对象。

function fn () { 
    'use strict';

    // malicious code

    arguments // still refers to the function's Arguments object
}

因此,无论在// malicious code注入什么代码,arguments标识符在整个函数调用期间都会不可变地绑定到函数的Arguments对象。

我想知道是否为eval标识符提供了相同的保证,即带有保证的eval标识符是否始终引用内置的全局eval函数?< / p>

我想指出,如果我们的严格代码嵌套在非严格代码中,则上面提到的保证是 not 。允许非严格代码创建本地"eval"绑定,或者改变全局"eval"绑定。 (另外,如果另一个非严格程序使用相同的全局对象(如在包含多个脚本的网页中),则也不提供上述保证。)

因此,为了这个问题,我想定义以下场景:

  • 我们的程序是独立的,即它不与任何其他程序共享其全局对象,
  • 我们的程序由一个严格的IIFE组成,如下所示:

    (function () {
        'use strict';
    
        // malicious code
    
        eval // does it still refer to the built-in global eval function? 
    
    }());
    

鉴于这些条件,是否可以在\\ malicious code注入代码,这将改变eval标识符的值?

2 个答案:

答案 0 :(得分:2)

理论上,根据附件C,不应该将eval标识符重新分配给全局对象的eval属性以外的其他属性,或者用局部变量对其进行掩码:

  

标识符eval或参数可能不会显示为赋值运算符(11.13)或PostfixExpression(11.3)的LeftHandSideExpression,也不会显示为由前缀增量(11.4.4)或前缀减量(11.4)操作的UnaryExpression。 5)运营商。

...

  

如果标识符“eval”或标识符“arguments”作为PropertyAssignment的PropertySetParameterList中的标识符出现,它包含在严格的代码中,或者如果其FunctionBody是严格的代码(11.1.5),那么这是一个SyntaxError。 p>

...

  

如果标识符eval或参数出现在严格模式FunctionDeclaration或FunctionExpression(13.1)的FormalParameterList中,则为SyntaxError

......等等。


如下所述,可以通过为全局对象的该属性分配新值来更改全局eval函数。可以通过在严格模式下间接调用eval来获取对全局对象的引用:

var glob = (0,eval)('this');

您可以将其扩展为在非严格模式下可靠运行的东西:

var glob = (function(){ return this || (0,eval)('this') }());

...然后将其eval属性分配给其他内容。

虽然eval仍然与全局对象的eval属性相同,但它不再是内置的eval,它应符合您的条件。

答案 1 :(得分:0)

不,据我所知,你不能在严格模式下覆盖本机eval函数。下面的代码会给出以下错误。 SyntaxError: Assignment to eval or arguments is not allowed in strict mode

(function () {
   'use strict';
   eval = function(){ console.log('eval invoked'); }  
   eval();  
}());