JavaScript可以轻松覆盖全局对象的属性和功能。我想找到一种方法来检查全局属性的原始版本是否已被替换。
考虑有人将其放入HTML:
<script type="text/javascript">
window.encodeURIComponent = eval;
</script>
<script type="text/javascript" src="myscript.js"></script>
如果myscript.js在某处调用encodeURIComponent函数,它现在将表现得不可预测。那么,如果有人在使用之前覆盖了该函数,我可以在myscript.js中查看吗?
答案 0 :(得分:7)
我唯一知道的是一种简单的方法,分析函数的字符串表示。通常,代码
window.encodeURIComponent.toString()
应该产生这样的东西:
function encodeURIComponent() { [native code] }
可以轻松解析关键信息function encodeURIComponent
。
如果eval
覆盖了该功能,如您的示例所示,您将获得:
function eval() { [native code] }
通常,要检查window
属性,您可以创建假iframe并将window.[property].toString()
与iframe.contentWindow.[property].toString()
进行比较。如果比较结果为false
,则该属性已更改。
答案 1 :(得分:3)
在一个脚本中执行此操作的一个有趣方法是比较函数原型
默认情况下 - typeof window.encodeURIComponent.prototype === "undefined"
但如果有人通过
重新定义了这个功能 window.encodeURIComponent = function() { eval(); }
我们会得到
typeof window.encodeURIComponent.prototype === "Object"
PS:这种方法比其他方法更可靠,但它不会给你100%的保证。 JavaScript是所有对象,并且都在运行时..只是活着......
<强>更新强> 你可以把两种方法结合起来..我的和@Stans ..
这个例子不起作用,因为我没有使用eval
- eval默认情况下还有原型“undefined”..所以你可以这样做
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
答案 2 :(得分: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!");
}
答案 3 :(得分:0)
在JavaScript中有一种简单的方法:)但你必须能够访问HTML,所以你不能在一个脚本中使用这个方法..
函数是一个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>
答案 4 :(得分:0)
这个怎么样?
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