Exposed: The Critical Multer Bug That Can Bring Your Server down

Express and Multer are popular for file uploads in Node.js, but a newly discovered bug could crash servers, leaving projects exposed. When Multer parses malformed requests, it may throw uncaught errors, causing server downtime. The unpredictable behavior can lead to instability. I’ve created this repository to show case the bug and a possible fix.

The repository has two branches, a main branch that demonstrates the bug and a multer-fix branch that provides a fix.

Below is the code for the express server, featuring two endpoints: one for health checking and another for avatar uploading, capable of handling multiple uploads. It also contains a hello-world.jpg for trigger the bug.

const express = require("express");
const multer = require("multer");
const upload = multer({ dest: "uploads" });
const PORT = 1337;

const app = express();

app.get("/health-check", function (req, res, next) {
  return res.json({ success: true });
});

app.post("/profile", upload.array("avatar"), function (req, res, next) {
  return res.json({ success: true });
});

process.on("uncaughtException", (err) => {
  if (err.message !== "Unexpected end of form") {
    // Gracefully shut down your application if it is not the uncatch bug from multer
    process.exit(1);
  }
});

app.listen(PORT, () => {
  console.log(`Express started at port:${PORT}`);
});

Clone and then Cd into repository. Run npm install once, then use npm run start to launch the server. You’ll see the following output in the console.

Express started at port:1337

Under normal circumstances, uploading “hello-world.png” to the “/profile” endpoint will return {“success”: true}. Here’s an example using cURL:

curl --location 'localhost:1337/profile' \
--form 'avatar=@hello-world.png'

To trigger the bug, intentionally let Multer handle a malformed form request, such as setting an incorrect Content-Length header. Using Content-Length: 1000 with “hello-world.png” consistently triggers this bug. Other content-length values may provoke the bug but not letting the express server down.

curl --location 'localhost:1337/profile' \
--header 'Content-Length: 1000' \
--form 'avatar=@hello-world.png'

The server is now down and unable to process any incoming requests.

The Fix

This issue has been reported on GitHub, and you can find it here. There are several potential fixes available:

  • The first fix is available in the multer-fix branch. It involves catching the unhandled exception in Node.js using the provided code.
process.on("uncaughtException", (err) => {
  if (err.message !== "Unexpected end of form") {
    // Gracefully shut down your application if it is not the uncatch bug from multer
    process.exit(1);
  }
});
  • Another option is to utilize patch-package to patch Multer yourself, as detailed in this PR.
  • Alternatively, consider using formidable instead of Multer as a solution.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *