5

JavaScriptを使用すると、グローバルオブジェクトのプロパティと関数を簡単に上書きできます。グローバルプロパティの元のバージョンが置き換えられているかどうかを確認する方法を見つけたいのですが。

これをHTMLに入れている人を考えてみましょう。

<script type="text/javascript">
    window.encodeURIComponent = eval;
</script>
<script type="text/javascript" src="myscript.js"></script>

myscript.jsがどこかでencodeURIComponent関数を呼び出すと、予期しない動作をするようになります。それで、myscript.js内で、使用する前に誰かがその関数を上書きしたかどうかを確認する方法はありますか?

4

5 に答える 5

8

私が知っている唯一のことは、関数の文字列表現を分析する簡単なアプローチです。通常、コード

window.encodeURIComponent.toString()

次のようなものを生成する必要があります:

function encodeURIComponent() { [native code] }

これは、キー情報を簡単に解析できますfunction encodeURIComponent

evalあなたの例のように、関数がによって上書きされた場合、次のようになります。

function eval() { [native code] }

一般に、windowプロパティを確認するために、偽のiframeを作成してと比較することができwindow.[property].toString()ますiframe.contentWindow.[property].toString()。比較するfalseと、プロパティが変更されています。

于 2012-04-22T08:39:16.843 に答える
3

これを 1 つのスクリプト内で行う興味深い方法の 1 つは、関数プロトタイプを比較することです。

デフォルトでは -typeof window.encodeURIComponent.prototype === "undefined"

しかし、誰かがこの関数を

window.encodeURIComponent = function() { eval(); } 私たちは得るだろう

typeof window.encodeURIComponent.prototype === "Object"

PS: この方法は他の方法よりも信頼性が高いですが、100% の保証はありません。JavaScript はすべてオブジェクトであり、すべて実行中です..これと一緒に暮らすだけです..

UPDATE 両方のメソッドを組み合わせることができます.. mineと@Stans ..

この例は、私が使用していなかったため機能しませんeval- eval もデフォルトで「未定義」のプロトタイプを持っています..これを行うことができます

window.encodeURIComponent.name === "encodeURIComponent" 
//to make shure that user won't use EVAL 
&& typeof window.encodeURIComponent.prototype === "undefined" 
//to make shure that user won't use self defined function
于 2012-04-22T09:29:08.267 に答える
1

これはブラウザ固有のものであり、関数以外では確実に機能しませんが、次のとおりです。

関数のtoStringメソッドを呼び出すと、次のようになります。

Chrome:

"function encodeURIComponent() { [native code] }"

Firefox:

"function encodeURIComponent() {
    [native code]
}"

IE 7/8/9:
"
function encodeURIComponent() {
    [native code]
}
" 

関数の名前がプロパティの名前と一致し、その本体が " [native code]" に置き換えられていることに注意してください。アイデアは、この文字列からすべての空白を削除し、期待される結果と比較すること"functionxxx(){[nativecode]}"です。

すべてのブラウザ/機能で機能するかどうかはわかりません。試行錯誤です。

var pattern = 'function' + propertyName + '(){[nativecode]}';
var func = window[propertyName].toString();
if(func.replace(/\s+/g, '') !== pattern) {
    throw new Error("Property window." + propertyName + " has been modified!");
}
于 2012-04-22T08:34:32.520 に答える
1

これはどう?

function isNativeWindowProperty(propertyName) {
    var result = false;
    var iframe = document.createElement('iframe');
    iframe.src = 'javascript:;';
    document.getElementsByTagName('body')[0].appendChild(iframe);
    if (window[propertyName].toString() === iframe.contentWindow[propertyName].toString()) {
        // check window[propertyName].toString override
        if (window[propertyName].toString.toString() === iframe.contentWindow[propertyName].toString.toString()) {
            result = true;
        }
    }
    iframe.parentNode.removeChild(iframe);
    return result;
};

console.log(isNativeWindowProperty('alert'));  // true

window.alert = function() {};
console.log(isNativeWindowProperty('alert'));  // false

window.alert.toString = function() {
    return 'function alert() { [native code] }';
};
console.log(isNativeWindowProperty('alert'));  // false
于 2015-05-05T13:57:39.047 に答える
0

JavaScript でそれを行う簡単な方法があります :) しかし、HTML にアクセスする必要があるため、1 つのスクリプト内でこのメソッドを使用することはできません..

function は OBJECT.. であるため、オブジェクトへのリンクを保存して、それらのリンクを比較するだけです。そのような関数を単純なオブジェクトと考えてください。オブジェクトをどのように比較できますか?

<script type="text/javascript">
    var a = window.encodeURIComponent;  // a === window.encodeURIComponent -> true
</script>
<script type="text/javascript">
    window.encodeURIComponent = eval; // a === window.encodeURIComponent -> false
</script>
<script type="text/javascript" src="myscript.js">
    if (a !== window.encodeURIComponent) 
    {
        throw new Error('Someone redefined function');
    }
</script>
于 2012-04-22T08:44:23.767 に答える