Overriding the prototype of an object and prohibiting any additional overrides

I am trying to write a library that intercepts all calls to XMLHttpRequest and does something before ultimately sending a request, overriding its prototype, for example:

var original_open = XMLHttpRequest.prototype.open;    
XMLHttpRequest.prototype.open = function() {
    // my own override logic here before running the original function
    original_open.apply(this, arguments);
};

The problem is that I want to ensure that when someone uses this library, it is not possible to override this effect for any other code on a web page.

Because otherwise, a website using this library might dynamically load another piece of JS code that simply overrides again XMLHttpRequest.prototype.open, and the whole purpose of this library is to prohibit this.

I was thinking about freezing the prototype, using Object.freeze()right after the override, so no other code can override my own override. The code will look something like this:

var original_open = XMLHttpRequest.prototype.open;    
XMLHttpRequest.prototype.open = function() {
    // my own override logic here before running the original function
    original_open.apply(this, arguments);
};
Object.freeze(XMLHttpRequest.prototype);

My expectation is that if another piece of code on the same page tries to override my own override, it will fail because the prototype was frozen.

My question is:

  • Is the right solution to this problem?
  • Is it really safe? (No loopholes)?
+6
source share
1 answer

.. , , . , , . , , .

- , . 5 , 5 .

, :

var old1 = Document.prototype.querySelector;
Document.prototype.querySelector = function(...args) {
  console.log('Override 1');
  return old1.call(this, ...args);
};

var old2 = Document.prototype.querySelector;
Document.prototype.querySelector = function(...args) {
  console.log('Override 2');
  return old2.call(this, ...args);
};

let p = document.querySelector('body');

console.log(p);
0

All Articles