5

A lot of the time, I write JavaScript that runs with other scripts or that may contain other scripts. Sometimes these scripts might have changed the prototypes for the primitive objects that I might be using in my code.

Is there a way I can declare my primitive datatypes in JavaScript so that it will reset the prototype if it has been modified? Or so that my scripts would run in a separate scope where the prototype of the primitive is not modified?

// evil script code modify primative on prototype
Boolean.prototype.toString = function() {
  return true;
}

let flag = false;
console.log(flag.toString());
// I would expect false to be printed, but because the prototype of the primative if overridden 
// the primative value would be wrapped with the Boolean object 
// and call the modified toString method and would output true.

Is there any way I can make sure my code is running in a separate scope, or any way I can declare my variables or reset the prototypes to avoid these types of issues?

kennarddh
  • 2,186
  • 2
  • 6
  • 21
user802599
  • 787
  • 2
  • 12
  • 35
  • This is one of the bad parts of javascript. Global scope is global. It affects everything in the VM. I would find the library doing that and remove the dependency if I could. There are some libraries that try to synchronize behaviors between different engines, but your example is not that – yxre Jun 19 '23 at 06:18
  • 1
    This is what ECMAScript Realms and Secure EcmaScript (SES) are for; ideally, they would solve this problem. – Sebastian Simon Jun 19 '23 at 06:25
  • 1
    "*I write JavaScript that runs with other scripts or that may contain other scripts.*" - what exactly is your use case? Are you writing a library? A browser extension content script? Something else? – Bergi Jun 19 '23 at 09:22

2 Answers2

2

You can freeze global object prototype but you need your script to run first. It will prevent modification.

I don't know how to freeze global function.

Object.freeze(String.prototype);
Object.freeze(Number.prototype);
Object.freeze(Boolean.prototype);
Object.freeze(Object.prototype);
Object.freeze(Array.prototype);
Object.freeze(Date.prototype);
Object.freeze(Math.prototype);
Object.freeze(Function.prototype);

// evil script code modify primative on prototype
Boolean.prototype.toString = function() {
  return true;
}

// For this I don't know how to freeze
window.parseInt = function(number) {
  return 'evil'
}

let flag = false;
console.log(flag.toString());

console.log(parseInt(1));
kennarddh
  • 2,186
  • 2
  • 6
  • 21
-3

Restore the original toString method of the Boolean prototype

Boolean.prototype.toString = function() {
  return Boolean(this) ? 'true' : 'false';
};

let flag = false;
console.log(flag.toString());

Try this please..