用Javascript对象替换窗口或文档对象

时间:2012-11-22 18:30:55

标签: javascript dom

有没有办法替换“窗口”或“文档”对象?我基本上想要的是提供某种JavaScript代理,我想阻止用户在页面上获得“SOME”(只有一些!这很重要)DOM元素。 “用户”是指任何第三个patty脚本。

我可以这样做:

document.getElementsByTagName("a")
//NodeList[129]
document.getElementsByTagName = function(){}
//function (){}
document.getElementsByTagName("a")
//undefined

但我能做些什么document.all如何替换DOM对象字段以使其仅返回DOM元素的“SOME”?

UPD :如果有办法用某些JavaScript对象替换'document'对象,那就更好了

UPD2 :我不在乎您的方法是否适用于'较旧'的浏览器。所以我对任何适用于“A”年级学生的解决方案都很好

UPD3 :我知道JavaScript中不存在100%的安全性,我不想阻止黑客“黑客攻击”,我知道这是不可能的,我想阻止开发人员那样做为我的“自制”框架写“插件”,做蠢事......

UPD4 :好的,我无法替换Document或Window,但我能否至少替换所有可返回“DOM”元素的“字段”或“函数”?比如“document.getElementById”或“document.all”?

UPD5 :用户@pebbl建议“关闭”我想要的东西

function a(window, document){
   /// in here window and document should be numerics
   alert(window);
   alert(document);
}

a(123,456);

但他的解决方案有一个大问题http://jsfiddle.net/kRLax/

UPD6-7 :这是'完美的'(至少对我而言)

http://jsfiddle.net/kRLax/12/

function Fx(){return function(){}}
function SafeThis(that){ 
    if (that == window) {
        return fakeWindow;
    } else if (that = document) {
        return fakeDocument;                    
    } else {
        return that;
    }
}
var fakeDocument = {
    write: function(a){ document.write(a) }
}
var fakeWindow = {
    document: fakeDocument
}

var moduleA = function(Function, window, document, eval){
    document.write(window + "<br>");
    var f = new Function("return this");
    document.write(f() + "<br>");
    var win = (function(){return this;})();
    document.write(win + "<br>");
    var e = eval("this"); 
    document.write(e + "<br>");
    document.write(this + "<br>");
    document.write(window + "<br>");
    document.write(document + "<br>");
    this.a = 1;
    document.write(JSON.stringify(this));
};

var moduleA_Fx = '!' + 
    moduleA.toString().replace(/\bthis\b/g,"SafeThis(this)") + 
    '(Fx,fakeWindow,fakeDocument,Fx)';

document.write(moduleA_Fx + "<br><br>");

eval(moduleA_Fx);
​

3 个答案:

答案 0 :(得分:1)

您只能重新分配可写属性,因此documentwindow不在考文范围内。

答案 1 :(得分:1)

"document"全局属性是不可写的,不可配置,所以不,你不能。

// try this in global code
Object.getOwnPropertyDescriptor( this, 'document' ).writable // false

答案 2 :(得分:1)

您可以执行以下操作,但您必须在函数范围内评估外部脚本:

function a(window, document){
  /// in here window and document should be numerics
  alert(window);
  alert(document);
}

a(123,456);

或者,如果你有一个服务器端代理,你可以用一个包装的匿名函数重写他们的代码,然后在你的代理文档和窗口对象中调用它。

;(function(window, document){

  /// the unknown external code here.

})(windowProxy, documentProxy);

然而,仍有办法解决这个问题,因为他们可能会根据JS环境使用以下内容:

var win = (function(){return this;})();

您可能还必须包含其他集合以确保无法访问它们:

;(function(window, document, all, images, ...){ ... }

但是,他们也可以通过您允许他们访问的任何dom元素访问原始document ...

关于UPD6

为了防止它有用,您可能还想插入以下漏洞:

  • 的setTimeout
  • 的setInterval

以上两者均可用于评估代码。

setTimeout('(function(){alert('+'th'+'is'+');})()');

另外,当您展示document.write时,这也是可行的:

document.write(
  '<img src="data:image/gif;base64,ERROR" '+
     'onerror="alert(th'+'is.ownerDocument);" />'
);

你应该阻止访问SafeThis并重写目标代码中的任何提及,否则可以覆盖:

SafeThis = function(that){return that;}

除此之外,虽然看起来很安全。我相信会有其他方法围绕它 - 如果你足够努力 - 但这实际上取决于你认为你可能的攻击者的确定程度;)