DEV Community

Kavishcan Veerasaravanan
Kavishcan Veerasaravanan

Posted on

CVE-2025–55182 Explained Simply

The Complete Patch: All Three Critical Fixes

Fix #1: Property Traversal in getOutlinedModel() (MOST CRITICAL)

What was broken:

// VULNERABLE CODE
const path = ref.split(':');
for (let i = 1; i < path.length; i++) {
  const name = path[i];
  value = value[name];  // NO CHECK - Can access __proto__, constructor, etc!
}
Enter fullscreen mode Exit fullscreen mode

The fix:

// PATCHED CODE
const path = ref.split(':');
for (let i = 1; i < path.length; i++) {
  const name = path[i];
  // CRITICAL FIX: Only access properties the object actually owns
  if (typeof value === 'object' && hasOwnProperty.call(value, name)) {
    value = value[name];
  } else {
    return undefined;  // Stop if property doesn't exist
  }
}
Enter fullscreen mode Exit fullscreen mode

What this line does:

  • hasOwnProperty.call(value, name) - Checks if the property exists on THIS object (not inherited from prototype)

How it blocks the exploit:

  • $1:__proto__:then → Tries to access __proto__BLOCKED (not own property)
  • $1:constructor:constructor → Tries to access constructorBLOCKED (not own property)
  • Without prototype access, the entire exploit chain collapses

Fix #2: Module Export Access in requireModule() (Defense-in-Depth)

What was broken:

// VULNERABLE CODE
export function requireModule<T>(metadata: ClientReference<T>): T {
  return moduleExports[metadata[NAME]];  // Can access prototype properties
}
Enter fullscreen mode Exit fullscreen mode

The fix:

// PATCHED CODE
if (hasOwnProperty.call(moduleExports, metadata[NAME])) {
  return moduleExports[metadata[NAME]];
}
return (undefined: any);  // Return undefined for prototype properties
Enter fullscreen mode Exit fullscreen mode

What this does:

  • Blocks access to inherited properties on module exports
  • Not the main vulnerability, but good defense-in-depth

Fix #3: Error Handling in decodeReplyFromBusboy()

What was broken:

// VULNERABLE CODE
resolveField(response, name, value);  // If this throws, server crashes
Enter fullscreen mode Exit fullscreen mode

The fix:

// PATCHED CODE
try {
  resolveField(response, name, value);
} catch (error) {
  busboyStream.destroy(error);  // Safely handle errors
}
Enter fullscreen mode Exit fullscreen mode

What this does:

  • Prevents server crashes that could leak information
  • Ensures graceful failure during exploitation attempts

Why The Fix Works: Breaking the Exploit Chain

The exploit required all these steps to work:

  1. Access __proto__ via $1:__proto__:thenBLOCKED by Fix #1
  2. Get Chunk.prototype.thenBLOCKED by Fix #1
  3. Trigger second deserialization → Still works, but useless now
  4. Access Function constructor via $1:constructor:constructorBLOCKED by Fix #1
  5. Execute malicious code → Can't reach this step anymore

Result: Single hasOwnProperty check breaks the entire chain.


Patched Versions

  • React: 19.0.1, 19.1.2, 19.2.1
  • Next.js: 15.1.8, 15.1.9, 15.2.4, 15.3.2

Update immediately if you're using React Server Components or Next.js App Router.

Top comments (0)