Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance and memory of prototype pollution vs dedicated library object

Not sure if this is a new question so pls ref to any good source if you have any.

My team is working on a big JS chart project we inherited from the previous developers who made intensive use of built-in objects prototypes for adding reusable code. We have a lot of new utility functions added to Date, Object and other intrinsic objects so I guess they went this way 'cause altering prototypes provides a bit more intuitive API.

On the other hand our component suffers from performance/memory gotchas and we apply all the possible optimizations and best practices. I can't find one regarding API design. I'm trying to figure out whether it's better to seed built-in objects' prototypes with library code instead of combining them in dedicated objects via somewhat namespace pattern.

The question is which design is better? And will one of them gain performance and/or memory over another?

Date.prototype.my_custom_function = new function (...) {...};
var period = new Date();
period.my_custom_function();

vs

DateLib.my_custom_function // defined in a DateLib function
var period = new Date();
DateLib.my_custom_function(period);

Thanks, guys, any help is appreciated!

EDIt: The main problem is that our component ended up being an awkward JS beast that slows down some mobile devices, especially old ones, such as iPad1 and early Androids... We've done a lot of optimization but I still see several questionable parts. I want to make sure if the built-in prototype pollution is another candidate to look into. Particularly, the Date and Object guys are heavily loaded with typical library code. For example, in fact the my_custom_function is a big big function and it's not the only additional member that sits on the Date prototype at code startup. The Object is loaded even more. Most of the client code doesn't make use of those additional features, it's used on purpose - so we're about to decide whichever way we're better stick with:

  • Keep using prototype pollution design
  • Refactoring reusable APIs into separate library static objects

to be honest I haven't run perf benchmarks yet, will do once I have time. If someone has outcome/ideas will be very helpful.

like image 639
Arman Avatar asked Sep 13 '13 09:09

Arman


People also ask

What is one method for stopping exploitations of an Object and preventing prototype pollution?

Another way to avoid prototype pollution is to consider using the Object. create() method instead of the object literal {} or the object constructor new Object() when creating new objects. This way, we can set the prototype of the created object directly via the first argument passed to Object.

What is Object prototype pollution?

In a prototype pollution attack, threat actors inject properties into existing JavaScript construct prototypes, attempting to compromise the application. This vulnerability is called prototype pollution because it allows threat actors to inject values that overwrite or pollute the “prototype” of a base object.

What is an example of prototype pollution?

Prototype Pollution is a vulnerability that allows attackers to exploit the rules of the JavaScript programming language, by injecting properties into existing JavaScript language construct prototypes, such as Objects to compromise applications in various ways. JavaScript allows all Object attributes to be altered.

What is prototype pollution in async?

1) Prototype pollutionThe vulnerability allows a remote attacker to escalate privileges within the application. The vulnerability exists due to improper input validation when handling data passed via the mapValues() method.


1 Answers

Modifying objects you don't own is definitely bad idea. The choice here is rather architectural: if you have to store a date persistently, then use a private property of the constructor:

function DateLib() {
  this._dateObject = new Date();
}

DateLib.prototype.getDateString = function () {
  return this._dateObject.toDateString()
};

var dateLib = new DateLib();
dateLib.getDateString();

If you just want to do some manipulation with a date, create a method:

var DateLib = {
  toDateString: function (date) {
    return date.toDateString()
  }
}

DateLib.toDateString(new Date());

As it comes to the performance, all approaches are equally fast (thanks to Bergi, alternative test by Esailija).

enter image description here

Note: this is not browser comparison test. Tests were performed on a different machines, so only method-vs-method performance should be analysed here.

like image 92
Pavlo Avatar answered Oct 03 '22 19:10

Pavlo