HIGH http request smugglingfeathersjsmongodb

Http Request Smuggling in Feathersjs with Mongodb

Http Request Smuggling in Feathersjs with Mongodb — how this specific combination creates or exposes the vulnerability

FeathersJS is a framework for creating JavaScript APIs with express-style request handling; it does not implement HTTP-level message parsing itself and relies on the underlying Node.js HTTP server and any configured middleware. When a FeathersJS service uses MongoDB as a persistence layer, the interaction between FeathersJS routing/hooks and the MongoDB driver becomes relevant to how requests are interpreted and processed.

Request smuggling arises when an HTTP request is parsed differently by a frontend proxy (such as a load balancer or CDN) and by FeathersJS (or the Node.js HTTP server). In a FeathersJS + MongoDB stack, this typically involves:

  • Inconsistent handling of request body lengths (e.g., Content-Length vs Transfer-Encoding), causing one request to be smuggled inside another.
  • Hooks that read the raw body or manipulate streams before the service handler processes parameters, potentially allowing a smuggled request to bypass intended route or service boundaries.
  • MongoDB operations that depend on parsed request parameters (e.g., user-supplied IDs or query filters). If a smuggled request changes the intended parameters, it can lead to data leakage or unauthorized data access across users stored in MongoDB collections.

For example, if a FeathersJS hook parses the body to enrich a params object before authentication logic runs, a smuggled request may cause the hook to process an unexpected set of parameters. Because FeathersJS services often pass params directly to MongoDB queries (e.g., find or patch using user-supplied IDs), this can unintentionally expose or modify other users’ documents if the injected request modifies identifiers or query filters. This does not require a remote code execution path; it can violate BOLA/IDOR checks and lead to horizontal privilege escalation where one user accesses or mutates another user’s MongoDB documents.

Additionally, if FeathersJS is fronted by a reverse proxy that buffers requests differently than the Node.js server, an attacker may craft requests where the front-end consumes the body but the backend interprets the remaining bytes as a new request. Because MongoDB operations are stateful and tied to the semantics of the params object, a smuggled request can execute unintended queries or updates, effectively changing the security boundary enforced by the application layer.

Mongodb-Specific Remediation in Feathersjs — concrete code fixes

Remediation focuses on ensuring consistent request parsing and strict validation of parameters before any MongoDB operation. Do not rely on request body being immutable between hooks; enforce strict parsing rules and validate all identifiers used in MongoDB queries.

Example: Safe FeathersJS service with validated MongoDB queries

// src/services/users/users.class.js
const { Service } = require('@feathersjs/feathers');
const mongodb = require('mongodb');

class UserService {
  constructor(options) {
    this.collection = options.db.collection('users');
  }

  async find(params) {
    // Ensure params.query is constrained and the caller cannot override projection or bypass filters
    const filter = params.query && params.query._id
      ? { _id: new mongodb.ObjectId(params.query._id) }
      : {};

    const cursor = await this.collection.find(filter, {
      projection: { email: 0, passwordHash: 0 } // explicitly exclude sensitive fields
    }).toArray();

    return cursor;
  }

  async get(id, params) {
    // Validate ID before using it in MongoDB
    if (!mongodb.ObjectId.isValid(id)) {
      throw new Error('Invalid object id');
    }
    const doc = await this.collection.findOne({ _id: new mongodb.ObjectId(id) });
    if (!doc) {
      throw new Error('Not found');
    }
    // Never return sensitive fields
    const { passwordHash, ...safeDoc } = doc;
    return safeDoc;
  }

  async create(data, params) {
    // Do not trust params for ownership; derive owner from authenticated context
    const userRecord = {
      _id: new mongodb.ObjectId(),
      name: data.name,
      email: data.email,
      ownerId: params.user ? params.user.userId : null
    };
    const result = await this.collection.insertOne(userRecord);
    return { id: result.insertedId.toString() };
  }
}

module.exports = function () {
  const app = this;
  app.use('/users', new UserService({ db: app.get('mongodb') }));
};

Key practices:

  • Validate and sanitize all IDs with ObjectId.isValid before constructing MongoDB queries.
  • Use projection to exclude sensitive fields (passwordHash, tokens) from query results.
  • Derive ownership (ownerId) from authenticated user context (params.user) rather than from user-supplied input that could be smuggled or tampered with.
  • Avoid passing raw query parameters directly into MongoDB filters without constraints; prefer whitelisting allowed query fields.

Middleware and hook hardening

Ensure hooks that read the body do not inadvertently change request semantics for subsequent hooks or service handlers. Prefer explicit parsing strategies and avoid streaming reuse across requests. For example, if you use raw body inspection, ensure it does not mutate the incoming stream in a way that affects later parsing:

// Example hook: validate body shape without side effects
const validateUserPayload = context => {
  const { name, email } = context.data || {};
  if (typeof name !== 'string' || !email || !email.includes('@')) {
    throw new Error('Invalid payload');
  }
  // Do not append or replace data in a way that could be reused by a smuggled request
  return context;
};

module.exports = {
  before: {
    create: [validateUserPayload],
    update: [validateUserPayload],
    patch: [validateUserPayload]
  }
};

By combining strict input validation, careful ownership derivation, and explicit MongoDB query constraints, the FeathersJS + MongoDB stack remains resilient against request smuggling attempts that target parameter manipulation or body parsing inconsistencies.

Frequently Asked Questions

How does middleBrick help detect request smuggling risks in a FeathersJS + MongoDB API?
middleBrick scans the unauthenticated attack surface and tests inconsistencies in request parsing (e.g., Content-Length vs Transfer-Encoding). Findings highlight smuggling indicators and map to OWASP API Top 10, with remediation guidance tailored to FeathersJS service patterns and MongoDB query usage.
Can I integrate middleBrick into CI/CD for a FeathersJS project using MongoDB?
Yes. With the Pro plan, you can use the GitHub Action to add API security checks to your CI/CD pipeline and fail builds if the risk score drops below your threshold, helping prevent regressions in FeathersJS services that rely on MongoDB.