检查是否已在JavaScript中覆盖全局属性/函数

GOT*_*O 0 5 javascript overwrite global-object

JavaScript可以轻松覆盖全局对象的属性和功能.我想找到一种方法来检查全局属性的原始版本是否已被替换.

考虑有人把它放在他们的HTML中:

<script type="text/javascript">
    window.encodeURIComponent = eval;
</script>
<script type="text/javascript" src="myscript.js"></script>
Run Code Online (Sandbox Code Playgroud)

如果myscript.js在某处调用encodeURIComponent函数,它现在将表现得不可预测.那么有一种方法可以检查myscript.js内部是否有人在使用之前覆盖了该功能?

Sta*_*tan 7

我唯一知道的是一种简单的方法,分析函数的字符串表示.通常,代码

window.encodeURIComponent.toString()
Run Code Online (Sandbox Code Playgroud)

应该产生这样的东西:

function encodeURIComponent() { [native code] }
Run Code Online (Sandbox Code Playgroud)

可以很容易地解析关键信息function encodeURIComponent.

如果函数被覆盖eval,如在您的示例中,您将获得:

function eval() { [native code] }
Run Code Online (Sandbox Code Playgroud)

在一般情况下,检查window属性,您可以创建一个假的iframe和比较window.[property].toString()iframe.contentWindow.[property].toString().如果比较给出false,则属性已更改.


DCo*_*der 1

这是特定于浏览器的,绝对不适用于非功能,但是:

调用函数的toString方法应该产生如下结果:

Chrome:

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

Firefox:

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

IE 7/8/9:
"
function encodeURIComponent() {
    [native code]
}
" 
Run Code Online (Sandbox Code Playgroud)

请注意,函数的名称与属性的名称相匹配,并且其主体被替换为“ [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!");
}
Run Code Online (Sandbox Code Playgroud)