CVE-2026-33993 Overview
CVE-2026-33993 is a Prototype Pollution vulnerability affecting the unserialize() function in the Locutus JavaScript library. Locutus is a library that brings standard library functions from other programming languages (such as PHP) to JavaScript for educational purposes. Prior to version 3.0.25, the unserialize() function in locutus/php/var/unserialize assigns deserialized keys to plain objects via bracket notation without filtering the __proto__ key. When a PHP serialized payload contains __proto__ as an array or object key, JavaScript's __proto__ setter is invoked, replacing the deserialized object's prototype with attacker-controlled content. This enables property injection, for...in propagation of injected properties, and denial of service via built-in method override.
Critical Impact
Attackers can inject arbitrary properties into JavaScript object prototypes through malicious PHP serialized payloads, potentially affecting all objects in the application and leading to denial of service conditions.
Affected Products
- Locutus versions prior to 3.0.25
- Node.js applications using the locutus/php/var/unserialize module
- Applications processing untrusted PHP-serialized data with Locutus
Discovery Timeline
- 2026-03-27 - CVE CVE-2026-33993 published to NVD
- 2026-04-01 - Last updated in NVD database
Technical Details for CVE-2026-33993
Vulnerability Analysis
This Prototype Pollution vulnerability exists in the unserialize() function, which is designed to parse PHP-serialized data into JavaScript objects. The root issue is that when deserializing arrays or objects from PHP serialization format, the function uses bracket notation (obj[key] = value) to assign properties without validating whether the key is a reserved JavaScript property name like __proto__.
JavaScript treats __proto__ as a special property that points to an object's prototype. When the unserialize() function processes a PHP serialized payload containing __proto__ as a key, it inadvertently triggers JavaScript's prototype setter mechanism. This allows an attacker to modify the prototype chain of the deserialized object with arbitrary attacker-controlled values.
The vulnerability enables several attack scenarios including property injection across all objects inheriting from the polluted prototype, unexpected behavior when iterating with for...in loops, and denial of service by overriding built-in methods like toString() or hasOwnProperty().
This vulnerability is distinct from previously reported prototype pollution issues in Locutus. The parse_str function was previously patched for similar issues (referenced in GHSA-f98m-q3hr-p5wq and GHSA-rxrv-835q-v5mh), but the unserialize function was not included in those mitigations.
Root Cause
The root cause is insufficient input validation during the deserialization process. The unserialize() function does not filter or sanitize object keys before assignment, allowing the special __proto__ property to be set through the standard property assignment mechanism. This bypasses the typical prototype chain protection that would exist if properties were assigned using safer methods like Object.defineProperty() with appropriate checks or by using Object.create(null) for the target object.
Attack Vector
The attack vector is network-based with no authentication required. An attacker can exploit this vulnerability by sending a crafted PHP-serialized payload to any application that uses the vulnerable unserialize() function. The malicious payload includes __proto__ as an object or array key with attacker-controlled values. When the application deserializes this payload, the prototype chain is polluted.
The attack flow involves the attacker crafting a PHP serialized string with a key named __proto__ containing malicious property values. When this payload reaches the vulnerable unserialize() function, the function parses the serialization format and attempts to reconstruct the JavaScript object. Upon encountering the __proto__ key, the bracket notation assignment invokes JavaScript's internal prototype setter, polluting the object prototype with the attacker's values. Subsequently, all objects that inherit from the polluted prototype may exhibit unexpected behavior, potentially leading to application crashes or security bypasses.
Detection Methods for CVE-2026-33993
Indicators of Compromise
- Presence of __proto__, constructor, or prototype strings in incoming PHP-serialized data payloads
- Unexpected application behavior or crashes in JavaScript object operations following deserialization
- Error logs showing TypeError exceptions related to overridden built-in methods like toString or valueOf
Detection Strategies
- Implement input validation to scan for prototype pollution payloads containing __proto__, constructor.prototype, or similar dangerous keys in serialized data
- Deploy Web Application Firewall (WAF) rules to detect and block PHP-serialized payloads containing prototype pollution patterns
- Monitor application logs for deserialization errors and unexpected type errors that may indicate exploitation attempts
Monitoring Recommendations
- Enable detailed logging on endpoints that accept PHP-serialized data and monitor for suspicious payloads
- Set up alerts for sudden increases in application errors related to object property access or method invocation failures
- Implement runtime application self-protection (RASP) solutions to detect prototype pollution attacks in real-time
How to Mitigate CVE-2026-33993
Immediate Actions Required
- Upgrade Locutus to version 3.0.25 or later immediately
- Audit all code paths that use the unserialize() function and ensure they do not process untrusted input without validation
- Implement input validation to reject serialized payloads containing dangerous prototype keys before passing them to unserialize()
Patch Information
The vulnerability has been patched in Locutus version 3.0.25. The fix is available in commit 345a6211e1e6f939f96a7090bfeff642c9fcf9e4. For additional details, review the GitHub Security Advisory GHSA-4mph-v827-f877 and the release notes for v3.0.25.
Workarounds
- If immediate patching is not possible, implement a wrapper function around unserialize() that validates input and rejects any serialized data containing __proto__, constructor, or prototype keys
- Consider freezing Object.prototype in controlled environments to prevent prototype modification, though this may impact application functionality
- Use Object.create(null) for objects that will receive deserialized data to create prototype-less objects that are immune to prototype pollution
# Update locutus to the patched version
npm update locutus@3.0.25
# Or install the specific patched version
npm install locutus@3.0.25
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


