3

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

我可以做这个:

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

但是我可以做些什么document.all来替换 DOM 对象字段以使其仅返回 DOM 元素的“某些”?

UPD:如果有办法用一些 JavaScript 对象替换“文档”对象,这会更好

UPD2:我不在乎您的方法是否不适用于“旧”浏览器。所以我对任何适用于“A”分级机的解决方案都很满意

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

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);
​
4

3 回答 3

1

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

于 2012-11-22T18:44:31.430 回答
1

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

// try this in global code
Object.getOwnPropertyDescriptor( this, 'document' ).writable // false
于 2012-11-22T18:45:51.377 回答
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, ...){ ... }

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

关于 UPD6

以防万一它有用,您可能还想堵住以下孔:

  • 设置超时
  • 设置间隔

以上都可以用来评估代码。

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;}

除此之外,虽然它看起来很安全。我相信还有其他方法可以绕过它——如果你足够努力的话——但这真的取决于你认为可能的攻击者有多坚定;)

于 2012-11-22T18:49:22.837 回答