What you need to know about prototype pollution and how it affects JavaScript

No, this is not about solid waste generated with the production of prototypes or models for different products. Prototype pollution here refers to a critical cyber threat rated 10/10 on the CVSS scale of severity.

In a paper published in July this year, entitled "Silent Spring: Prototype Pollution Leads to Remote Code Execution in Node.js," security researchers revealed a serious vulnerability that affects prototype-based languages like JavaScript and the Node.js platform. This threat involves injecting properties into an object's root prototype at runtime and causes the execution of legit code gadgets.

The researchers developed a framework built on top of CodeQL to detect prototype pollution by employing both dynamic and static analysis. Using this framework, they were able to identify 11 universal gadgets that can potentially enable remote code execution in the code Node.js API.

What exactly is prototype pollution?

As mentioned, prototype pollution is a cyber vulnerability designed to allow threat actors to exploit JavaScript runtimes. It results in security compromises as it enables the introduction of properties into existing JavaScript construct prototypes.

The name of this threat is actually a description of how it operates. It makes it possible to inject values that overwrite the "prototype" of a base object. This means that a prototype is essentially "polluted," resulting in the creation of a malicious prototype that can then be passed to other objects that inherit the prototype.

With threat actors being able to control the values of object properties, they can modify an application's logic and launch attacks such as denial of service, privilege escalation, and remote code execution among others.

The emergence of prototype pollution

Before discussing the details of how prototype pollution took place, here’s a definition of the important terms involved in the existence of prototype pollution.

  • Object -- This refers to everything inputted in JavaScript except the primitives.
  • Prototype -- This is a mechanism that allows JavaScript objects to take on features from other objects.
  • __proto__ -- This is an attribute that has been standardized across browsers. It refers to the prototypes of an object.

Prototype pollution happens when a threat actor manages to take over the __proto__ attribute, having the ability to manipulate the values for this attribute. They usually do this by adding a new prototype into the __proto__ attribute. The introduction of a new prototype has the effect of making all objects inherit the injected prototype since each JavaScript object already has the __proto__ attribute and inherits prototypes.

The manipulation of the __proto__ attribute allows the modification of the properties of an existing JavaScript code, which can result in a number of possible consequences, including denial of service (DoS), remote code execution (RCE), SQL injection, cross-site scripting (XSS), privilege escalation, and other unwanted outcomes.

From exploitation to attack

To emphasize, prototype pollution is not itself the attack. It is a vulnerability that can result in cyberattacks when exploited. When the vulnerability exploitation results in the crashing of a server, DoS happens. Denial of service may not sound that threatening, but a Ponemon Institute study says that a DoS can cost $22,000 for every minute of downtime.

Remote code execution can be triggered through the creation of a reverse shell similar to what happened with the data visualization library called Kibana. Also, cybercriminals can launch an SQL injection attack just like what happened a couple of years ago with the JavaScript library TypeORM. Additionally, threat actors can trigger client-side JavaScript code execution by exploiting the prototype pollution vulnerability in gadgets that rely on the property of an object.

Meanwhile, attackers with more advanced prototype pollution knowledge can undertake server-side exploitation, which typically has a more severe impact as compared to its client-side counterpart. Server-side exploitation can also lead to SQL injection, remote code execution, and bypassed authorization and authentication.

How to combat prototype pollution

Prototype pollution is a complex problem, but it is not without solutions. There are three main ways to avoid it and mitigate its impact.

  • Ascertain the security of the open source libraries used --  The use of open source libraries is normal practice, but this does not mean that it is mostly a safe and secure practice. It is recommended to double-check the sources of libraries to use to ensure that they are free from vulnerabilities that can lead to security compromises. Often, the issues in them are not purposely added, but they develop as a result of different events including the merging of two objects, deep cloning of objects, and the generation of objects through recursively zipping properties with values.
  • Avoid creating objects with Java prototypes -- Instead of using the object constructor "Object()or the object-literal {}" when creating a new object, it is better to use "Object.create()". This method is preferable because it enables the setting of the created object's prototype using the first argument passed to the object. With this, passing a null value means that there will be no prototype for the created object. Hence, the new object becomes free from possible pollution because there is no prototype to be polluted in the first place.
  • Restrict all changes to the prototype -- JavaScript makes it possible to block all changes attempted on a prototype through Object.freeze(). This prevents all possible changes to an object's attributes. Alternatively, the nopp npm package can be installed. Doing this automatically freezes all common object prototypes, to prevent any change in the prototype.
  • JSON input schema validation -- This approach rejects unnecessary attributes from being adopted. To have schema validation of JSON input, it is important to use a library on npm such as ajv. Schema validation ascertains that the JSON data has all the attributes expected in it including the appropriate data type.
  • Use map in lieu of object -- Whenever a key/value structure is produced, it is advisable to use "map" instead of "object." This solution operates like a HashMap with the exception that it can only be consumed

Key takeaways

Prototype pollution is not a minor threat. It is a vulnerability that can have serious consequences when exploited. It can cause costly interruptions because of denial of service. Furthermore, it is reassuring to know that there are relatively simple ways to address this problem. Even better, there are comprehensive advanced solutions that can protect JavaScript from attacks and prevent the exploitation of the prototype pollution vulnerability.

Image Credit: Pixabay

Peter Davidson works as a senior business associate helping brands and start ups to make efficient business decisions and plan proper business strategies. He is a big gadget freak who loves to share his views on latest technologies and applications.

Comments are closed.

© 1998-2024 BetaNews, Inc. All Rights Reserved. Privacy Policy - Cookie Policy.