Unsafe Deserialization in NodeJS
Vulnerable example
Unlike PHP or Java, Node.js (JavaScript) does not provide advanced forms of object serialization, yet the JSON (JavaScript Object Notation) format is often used to convert JavaScript data object from/to a string representation. Before the relative recent addition of the JSON.parse
method to ECMAScript, developers used to deserialize objects using the eval
function. The following snippet illustrates this bad practice:
function myJSONParse(data) {
return eval(`(${data})`);
}
If data
is controlled by the attacker, it becomes trivial to inject arbitrary JavaScript code. For example, the following invocation executes a shell script that writes the output of the id
command to /tmp/proof
:
myJSONParse("require('child_process').exec('id > /tmp/proof')")
Prevention
The correct way to serialize and deserialize JavaScript objects is to use the provided JSON
global object. For example:
const object = {foo: 123};
JSON.stringify(object) // '{"foo":123}'
JSON.parse('{"foo":123}') // { foo: 123 }
References
Wikipedia - Serialization OWASP - Insecure Deserialization MDN - JSON