严格模式提供的保证之一是,在严格函数代码中,标识符 arguments
始终引用该函数的 Arguments 对象。
function fn () {
'use strict';
// malicious code
arguments // still refers to the function's Arguments object
}
因此,无论在//恶意代码
中注入(inject)什么代码,arguments
标识符在整个函数调用过程中都会不可变地绑定(bind)到函数的Arguments对象。
我想知道是否为 eval
标识符提供相同的保证,即带有保证的 eval
标识符是否引用内置的全局 eval
始终起作用?
我想指出,如果我们的严格代码嵌套在非严格代码中,则不会提供上述保证。允许非严格代码创建本地 "eval"
绑定(bind),或改变全局 "eval"
绑定(bind)。 (此外,如果另一个非严格程序使用相同的全局对象(如在包含多个脚本的网页中),也不会提供上述保证。)
因此,为了这个问题,我想定义以下场景:
- 我们的程序是独立的,即它不与任何其他程序共享其全局对象,
我们的程序由一个严格的 IIFE 组成,如下所示:
(function () { 'use strict'; // malicious code eval // does it still refer to the built-in global eval function? }());
考虑到这些条件,是否有可能在\\恶意代码
处注入(inject)代码,从而改变eval
标识符的值?
最佳答案
理论上,应该不可能将 eval
标识符重新分配给全局对象的 eval
属性之外的其他内容,或者根据局部变量对其进行屏蔽附件C:
The identifier eval or arguments may not appear as the LeftHandSideExpression of an Assignment operator (11.13) or of a PostfixExpression (11.3) or as the UnaryExpression operated upon by a Prefix Increment (11.4.4) or a Prefix Decrement (11.4.5) operator.
...
It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code or if its FunctionBody is strict code (11.1.5).
...
It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1)
...等等。
如下所述,可以通过为全局对象的该属性分配新值来更改全局 eval 函数。在严格模式下,可以通过间接调用eval
来获取对全局对象的引用:
var glob = (0,eval)('this');
您可以将其扩展到在非严格模式下也能可靠工作的东西:
var glob = (function(){ return this || (0,eval)('this') }());
...然后将其 eval
属性分配给其他内容。
虽然eval
仍然与全局对象的eval
属性相同,但它不再是内置的eval
,应该符合您的条件。
关于javascript - 是否可以在严格代码中更改标识符 `eval` 的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12627385/