code

Server-Side Prototype Pollution

Written by Bar Hajby on

Server-Side Prototype Pollution

Written by Bar Hajby on


Introduction

While not as widely recognized as other web vulnerabilities, prototype pollution has gained significant attention in recent years due to its potential impact on both client-side and server-side applications. This vulnerability occurs when an attacker manages to inject properties into JavaScript’s global object prototype. Because almost every object in JavaScript inherits from this prototype, a successful injection can change application behavior in unexpected and often dangerous ways.

On the client side, this could allow an attacker to manipulate logic in the browser, bypass security controls, or even trigger cross-site scripting when the polluted properties reach dangerous sinks. On the server side, the risks can be more critical. Applications running on Node.js or similar environments often use objects for configuration, authentication, and data handling. A polluted prototype in this context may lead to privilege escalation, denial of service, or, in certain cases, remote code execution.

This article explores the mechanics of server-side prototype pollution, examines attack scenarios and consequences in Node.js and similar environments, and outlines practical steps to prevent applications from this vulnerability.

What is Prototype Pollution?

Prototype pollution is a JavaScript vulnerability that lets attackers modify base object prototypes. As a result, all objects in the application inherit attacker-controlled properties. Server-side prototype pollution happens when attackers inject special keys like __proto__, constructor, or prototype. This lets them add or change properties every object inherits, even ones created after the pollution.

For example, with an input like:

{“__proto__”: {“isAdmin”: true}}

The property isAdmin might be included on objects throughout the application, even though it was never explicitly set by the code.

How Does Prototype Pollution Occur?

Prototype pollution typically arises when applications or third-party libraries handle user input unsafely. Common scenarios include:

  • Insecure object merging: Functions such as Object.assign or libraries like lodash.merge combine objects without filtering dangerous keys.
  • Unsafe deserialization: Directly parsing user input in JSON or YAML without validation.
  • Outdated dependencies: Older versions of libraries (for example, lodash, jQuery, or hoek) that did not account for __proto__ injections.
  • Configuration loading: Insecure loading of configuration files or API input that merges untrusted data with sensitive application objects.
Image No. 1 – A Flowchart Describing the Server-Side Prototype Pollution Attack

Attack Scenario

To better understand how server-side prototype pollution can be exploited, consider the following lab scenario from PortSwigger’s lab.
The application allows users to update their profile information, and the JSON request body is merged directly into server-side objects without filtering dangerous keys. By injecting the payload {“__proto__”: {“isAdmin”: true}} into the profile update request, the attacker pollutes the global prototype. As a result, all objects across the application now inherit the property isAdmin: true.

Image No. 2 – The Prototype Object has Been Successfully Polluted

With the prototype polluted, the attacker gains elevated privileges. The attacker can now access the admin panel without authorization because the server checks the inherited isAdmin property. From there, they can delete users and perform other admin actions, showing how one request can compromise the entire application.

Image No. 3 – Successfully Using the Administrator Privileges

Consequences

The consequences of a server-side prototype pollution vulnerability can be severe. The following are some of the attack scenarios that may arise from this weakness:

  • Privilege Escalation: Adversaries can inject properties such as isAdmin: true into the prototype chain, allowing them to bypass authorization checks and gain administrative access
  • Denial of Service: By overwriting fundamental object properties like toString, attackers can cause applications to crash or behave unpredictably, resulting in service disruption.
  • Remote Code Execution: In certain cases, polluted properties may reach unsafe execution contexts, enabling attackers to run arbitrary code on the server.
  • Logic Manipulation: Attackers can alter application behavior by modifying properties that control configuration, feature toggles, or security checks, leading to unintended or harmful outcomes.

Mitigation

Preventing server-side prototype pollution requires a combination of secure coding practices and proper dependency management:

  • Input Validation: Validate and sanitize user input before processing. Specifically block dangerous keys such as __proto__, constructor, and prototype.
  • Safe Object Handling: Avoid unsafe object merging functions or use libraries that are hardened against prototype pollution.
  • Update Dependencies: Keep JavaScript libraries and frameworks up to date, as many prototype pollution issues arise from outdated versions.
  • Secure Parsing: Use safe parsers for JSON, YAML, or other formats that do not allow prototype manipulation by default.

Conclusion

Server-side prototype pollution vulnerabilities are a subtle yet powerful threat with severe consequences if not addressed. Organizations can significantly reduce the risk by understanding how these attacks occur and taking proactive steps to validate input, manage dependencies, and adopt secure coding practices. Regular reviews of application logic, dependency updates, and developer awareness are crucial to ensuring that applications remain protected against this class of attacks.

Staying vigilant and proactive is the best defense against prototype pollution. By securing the way objects and input are handled, applications maintain their core functionality while preserving user trust. Organizations should prioritize security assessments and penetration testing to identify prototype pollution risks early, which is especially important when developing and maintaining modern JavaScript and Node.js applications.

References