2

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

function fn () { 
    'use strict';

    // malicious code

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

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

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

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

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

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

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

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

4

2 回答 2

2

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

标识符 eval 或 arguments 不能显示为赋值运算符 (11.13) 或 PostfixExpression (11.3) 的 LeftHandSideExpression 或由前缀增量 (11.4.4) 或前缀减量 (11.4.5) 运算符操作的 UnaryExpression .

...

如果标识符“eval”或标识符“arguments”作为包含在严格代码中的 PropertyAssignment 的 PropertySetParameterList 中的标识符出现,或者如果其 FunctionBody 是严格代码 (11.1.5),则为 SyntaxError。

...

如果标识符 eval 或 arguments 出现在严格模式 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,应该满足您的条件。

于 2012-09-27T18:07:22.790 回答
0

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

(function () {
   'use strict';
   eval = function(){ console.log('eval invoked'); }  
   eval();  
}());
于 2012-09-27T18:05:10.753 回答