Http Request Smuggling in Express with Mongodb
Http Request Smuggling in Express with Mongodb — how this specific combination creates or exposes the vulnerability
HTTP request smuggling occurs when an attacker sends specially crafted requests that are interpreted differently by frontend proxies (such as load balancers or API gateways) and the Express application. In an Express service that uses Mongodb as its backend datastore, the risk is amplified when parsing logic, body handling, or route merging interacts with untrusted input. A common pattern is Express apps that accept JSON, urlencoded, or raw bodies while also proxying or being deployed behind non-strict parsers.
Consider an Express route that merges user-supplied parameters into a database query without strict validation:
app.get('/products/:category', async (req, res) => {
const client = await MongoClient.connect(process.env.MONGO_URI);
const db = client.db('shop');
const category = req.params.category;
const cursor = db.collection('items').find({ category: category });
const items = await cursor.toArray();
res.json(items);
});
If this route is placed behind a proxy that normalizes or duplicates headers (e.g., handling Content-Length inconsistently), an attacker can smuggle a second request via the request body. Because the route uses req.params.category directly and does not validate the origin of the request, a smuggled request could reach the same handler with an unexpected path or body, potentially bypassing intended access controls or causing data leakage from Mongodb collections.
The vulnerability is not inherent to Mongodb, but to how Express routes are defined and how body parsing is configured. If the app uses the body-parser middleware with strict JSON parsing disabled, or uses merge methods that allow prototype pollution, a smuggled request may manipulate the query sent to Mongodb. For instance, an attacker might inject a payload that modifies the effective query filter, leading to Insecure Direct Object Reference (IDOR) or unauthorized data exposure across collections.
In environments where Express sits behind an API gateway or load balancer that buffers and forwards requests, inconsistent handling of Transfer-Encoding and Content-Length headers creates the conditions for smuggling. Because Mongodb operations often rely on the structure of the parsed request, a smuggled request can change the intended query or update target, escalating the impact to data integrity or confidentiality.
Mongodb-Specific Remediation in Express — concrete code fixes
Remediation focuses on strict input validation, safe query construction, and hardened Express configurations that prevent ambiguous parsing by frontends. Follow these patterns when working with Mongodb in Express.
- Use explicit route parameters and reject unexpected paths:
const allowedCategories = ['books', 'electronics', 'clothing'];
app.get('/products/:category', async (req, res) => {
if (!allowedCategories.includes(req.params.category)) {
return res.status(400).json({ error: 'invalid category' });
}
const client = await MongoClient.connect(process.env.MONGO_URI);
const db = client.db('shop');
const items = await db.collection('items').find({ category: req.params.category }).toArray();
res.json(items);
});
- Validate and sanitize all user input before building queries to avoid injection and smuggling:
const { body, validationResult } = require('express-validator');
app.post('/orders', [
body('productId').isMongoId(),
body('quantity').isInt({ gt: 0 })
], async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const client = await MongoClient.connect(process.env.MONGO_URI);
const db = client.db('shop');
const result = await db.collection('orders').insertOne({
productId: req.body.productId,
quantity: req.body.quantity,
createdAt: new Date()
});
res.status(201).json({ _id: result.insertedId });
});
- Configure body parsers explicitly and avoid merging untrusted bodies:
const express = require('express');
const app = express();
app.use(express.json({ type: 'application/json' }));
app.use(express.urlencoded({ extended: false }));
// Avoid using merged or overridden body parsing in routes susceptible to smuggling
- Apply strict CORS and header normalization policies to reduce header ambiguity:
const cors = require('cors');
app.use(cors({
origin: 'https://trusted.example.com',
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true
}));
- Use MongoDB features that enforce schema and type checks where possible, and avoid dynamic concatenation of collection or field names derived from user input.