---
A serious security flaw has been uncovered in the popular serialize-javascript npm package. Tracked as CVE-2024-11831, this vulnerability has wide-reaching consequences for web applications that transmit serialized JavaScript objects to clients.
In this post, I’ll break down what the vulnerability is, how it works, and show with simple examples how attackers can exploit it. I’ll also include references to the original advisory and tip you on fixing the issue.
What Is serialize-javascript?
serialize-javascript is a widely used npm library to serialize JavaScript objects into strings. Web apps and frameworks use it for server-side rendering, templating, and passing JavaScript data to browser clients.
The Vulnerability Explained
CVE-2024-11831 arises because serialize-javascript does not sanitize certain input types, specifically regular expressions or crafted objects. If an attacker can force the server to serialize a malicious value and send it to a client—such as embedding data in a webpage—they can execute arbitrary code in the user’s browser. This is a classic Cross-Site Scripting (XSS) vulnerability.
This issue has a critical severity rating and is especially dangerous in any environment where user-provided data is serialized and served to the client.
How Does It Work?
The core of the issue: serialize-javascript will turn certain JavaScript objects—including regexes—directly into strings that could include executable code. If an attacker controls any of this input, they can inject JavaScript that will run as soon as the page loads.
When combined with template engines or SSR (Server Side Rendering) frameworks that use this library, the risk multiplies.
Here’s a simple Node.js scenario showing the exploit in action
const serialize = require('serialize-javascript');
const express = require('express');
const app = express();
// Simulate untrusted input coming from a request
app.get('/', (req, res) => {
// The attacker sends data like: /?payload=/foo/;alert('XSS');//
let payload = req.query.payload || "regular value";
// Not recommended: directly serializing user input!
const serialized = serialize({ data: eval(payload) });
res.send(`
<html>
<body>
<script>
// Data is embedded directly into JavaScript context
var serverData = ${serialized};
</script>
</body>
</html>
`);
});
app.listen(300, () => console.log("Listening..."));
EXPLOIT:
If the attacker visits:
http://localhost:300/?payload=/foo/;alert('XSS');//
The serialized output is
var serverData = { data: /foo/;alert('XSS');// };
Result: The alert('XSS') executes in the client’s browser as soon as the page loads. This is a classic XSS.
Widespread Use: Many web frameworks depend on serialize-javascript under the hood.
- Stealth: An attacker only needs to control data that ends up being serialized. No need to upload scripts or bypass other protections.
Upgrade:
Update to the latest version of serialize-javascript (>=6..1), which fixes this vulnerability.
Extra Protection:
Use strong Content Security Policy (CSP) headers to limit what executable scripts can do.
References
- NVD Advisory for CVE-2024-11831
- GitHub Security Advisory for serialize-javascript
- Release notes fixing the bug
Summary
CVE-2024-11831 is a critical XSS vulnerability in the serialize-javascript npm package. The root cause is a lack of input sanitization for objects like regex. If you’re using this library to serialize data sent to browsers, upgrade now and check your code for unsafe serialization patterns. XSS bugs can be devastating—so patch quickly and review your templates!
Timeline
Published on: 02/10/2025 16:15:37 UTC
Last modified on: 02/13/2025 22:39:49 UTC