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)
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:
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.
There would still be ways around this however, as they might be able to use the following depending on the JS environment:
You may also have to include the other collections to make sure they are not accessible:
But, they would also be able to access the original
documentthrough any dom elements you allowed them access to as well…With regards to UPD6
Just in case it’s useful you may also want to plug the following holes:
Both the above can be used to evaluate code.
Plus as you are exposing
document.writethis would also be feasible:And you should block access to
SafeThisand rewrite any mention of it in the target code, otherwise it can be overriden: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 😉