Is there a way to replace "window" or "document" objects? What I basically want is to provide some kind of JavaScript Proxy, I want to prevent user from getting "SOME" (only some! this is important) DOM element's on the page. By "user" I mean any third patty script.
I can do this:
document.getElementsByTagName("a")
//NodeList[129]
document.getElementsByTagName = function(){}
//function (){}
document.getElementsByTagName("a")
//undefined
But what I can do about document.all how can I replace DOM object field to make it return only "SOME" of the DOM elements?
UPD: If there is a way to replace 'document' object with some JavaScript object this would be much more better
UPD2: I don't care if your method won't work on 'older' browsers. So i'm good with any solution that works on "A" graders
UPD3: I know that 100% security doesn't exist in JavaScript, I don't want to prevent hackers from "HACKING", I know it's not possible, I want to prevent developers that write "plugin" for my "home made" framework, to do stupid things..
UPD4: ok, I can't replace Document nor Window, but can I at least replace all "fields" or "functions" that repsonsoble for returning "DOM" elements? like "document.getElementById" or "document.all" ?
UPD5: User @pebbl suggested something that 'close' to the thing I want
function a(window, document){
/// in here window and document should be numerics
alert(window);
alert(document);
}
a(123,456);
but his solution have one big problem http://jsfiddle.net/kRLax/
UPD6-7: This is the 'perfect' one (at least for me)
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);
You can do the following, but you would have to eval the external script within your function's scope:
function a(window, document){
/// in here window and document should be numerics
alert(window);
alert(document);
}
a(123,456);
Or if you had a server-side proxy you could rewrite their code with a wrappered anon function that then called in your proxy document and window object.
;(function(window, document){
/// the unknown external code here.
})(windowProxy, documentProxy);
There would still be ways around this however, as they might be able to use the following depending on the JS environment:
var win = (function(){return this;})();
You may also have to include the other collections to make sure they are not accessible:
;(function(window, document, all, images, ...){ ... }
But, they would also be able to access the original document through any dom elements you allowed them access to as well...
Just in case it's useful you may also want to plug the following holes:
Both the above can be used to evaluate code.
setTimeout('(function(){alert('+'th'+'is'+');})()');
Plus as you are exposing document.write this would also be feasible:
document.write(
'<img src="data:image/gif;base64,ERROR" '+
'onerror="alert(th'+'is.ownerDocument);" />'
);
And you should block access to SafeThis and rewrite any mention of it in the target code, otherwise it can be overriden:
SafeThis = function(that){return that;}
Other than that though it seems quite secure. I'm sure there will be other ways round it—if you try hard enough—but it really depends on how determined you think your possible attackers might be ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With