2

strictモードが提供する保証の1つは、strict関数コードでは、識別子argumentsが常にその関数のArgumentsオブジェクトを参照することです。

function fn () { 
    'use strict';

    // malicious code

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

したがって、どのコードがに挿入されても、関数の呼び出し全体を通じて// malicious codearguments識別子は関数のArgumentsオブジェクトに不変にバインドされます。

同じ保証がeval識別子に提供されているかどうか疑問に思いました。つまり、保証付きの識別子は常にeval組み込みのグローバル関数を参照していますか?eval

厳密なコードが非厳密なコード内にネストされている場合、上記の保証は提供されないことを指摘しておきます。非厳密なコードでは、ローカル"eval"バインディングを作成したり、グローバル"eval"バインディングを変更したりできます。(また、(複数のスクリプトを含むWebページのように)別の非厳密なプログラムが同じグローバルオブジェクトを使用する場合、上記の保証も提供されません。)

したがって、この質問のために、次のシナリオを定義したいと思います。

  • 私たちのプログラムはスタンドアロンです。つまり、グローバルオブジェクトを他のプログラムと共有しません。
  • 私たちのプログラムは、次のように単一の厳密な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

eval理論的には、識別子をグローバル オブジェクトのプロパティ以外のものに再割り当てしevalたり、ローカル変数でマスクしたりすることはできないはずです。

識別子 eval または引数は、Assignment 演算子 (11.13) または PostfixExpression (11.3) の LeftHandSideExpression として、または Prefix Increment (11.4.4) または Prefix Decrement (11.4.5) 演算子によって操作される UnaryExpression として表示されない場合があります。 .

...

識別子「eval」または識別子「arguments」が厳密なコードに含まれる PropertyAssignment の PropertySetParameterList の識別子として発生する場合、またはその FunctionBody が厳密なコード (11.1.5) である場合は、SyntaxError です。

...

識別子 eval または引数が厳密モードの FunctionDeclaration または FunctionExpression (13.1) の FormalParameterList 内にある場合は、SyntaxError です。

...等々。


以下で説明するように、グローバル オブジェクトのそのプロパティに新しい値を割り当てることで、グローバル eval 関数を変更することができます。evalグローバル オブジェクトへの参照は、strict モードでを間接的に呼び出すことで取得できます。

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

非厳密モードでも確実に機能するものにそれを拡張できます。

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

...そして、そのevalプロパティを別のものに割り当てます。

グローバルオブジェクトevalのプロパティと同じままですが、組み込みではなくなり、条件を満たしているはずです。evaleval

于 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 に答える