HIGH integrity failuresfeathersjsmongodb

Integrity Failures in Feathersjs with Mongodb

Integrity Failures in Feathersjs with Mongodb — how this combination creates or exposes the vulnerability

FeathersJS is a framework that encourages a service-oriented architecture where services expose methods (e.g., find, get, create, update, patch) often backed by a database adapter such as @feathersjs/adapter-mongodb. When application logic does not enforce strict ownership and authorization checks across service methods, and when Mongodb queries are constructed from untrusted input, integrity failures occur. These failures typically map to BOLA/IDOR and BFLA/Privilege Escalation checks in middleBrick scans, because an attacker can manipulate identifiers (IDs) or context to access or modify data they should not.

With Mongodb, integrity risks arise from several patterns: using request parameters directly in filters without scoping to the requesting user, omitting $and/$or conditions that enforce tenant or user boundaries, and allowing partial updates via patch that can overwrite fields that should be immutable (e.g., role, isAdmin). For example, a find call that uses req.query.id without ensuring the record belongs to the same tenant or team enables horizontal privilege escalation. Similarly, an update route that applies req.patch directly without validating which fields are mutable can lead to vertical escalation by changing role or permissions stored in Mongodb documents. These issues are especially pronounced when services share a Mongodb collection and the adapter does not enforce row-level or tenant-level scoping automatically.

Real-world attack patterns include changing another user’s email by supplying an _id that does not belong to them, or escalating privileges by setting isAdmin to true via a loosely guarded patch. In MongoDB, injection techniques are less about traditional SQL injection and more about ensuring query filters are correctly scoped and immutable fields are protected from mass assignment. middleBrick tests these scenarios by probing endpoints with modified identifiers and observing whether unauthorized data is returned or modified, referencing OWASP API Top 10 A01:2023 Broken Object Level Authorization and relevant PCI-DSS controls when access controls are missing.

To illustrate, consider a Feathers service for user profiles where the Mongodb adapter is used without ownership checks:

// services/user-profiles/user-profiles.class.js
const { Service } = require('@feathersjs/feathers');
const mongodb = require('@feathersjs/adapter-mongodb');
const app = require('feathers')();
const { MongoClient } = require('mongodb');

let client;
async function getDb() {
  if (!client) {
    client = new MongoClient('mongodb://localhost:27017');
    await client.connect();
  }
  return client.db('myapp');
}

app.use('/profiles', mongodb(getDb(), {
  collection: 'profiles'
}));

const service = app.service('profiles');

// Risky update without ownership validation
app.hooks({
  before: {
    async patch(id, data, params) {
      // Missing check that the profile belongs to params.account.userId
      // This can allow IDOR if id is user-controlled
    }
  }
});

In this setup, an attacker who knows another profile’s _id can patch fields such as role or email. middleBrick’s BOLA and Property Authorization checks flag this by submitting modified IDs and inspecting whether the operation is permitted, and by checking whether updates affect sensitive properties without authorization.

Another integrity failure scenario arises from unsafe consumption of query parameters in Mongodb filters. If a service builds a filter like { _id: req.query.id } without verifying that req.query.id aligns with the requesting user’s context, it can read or modify unrelated records. Using $in with user-controlled arrays also risks unintended data exposure if array elements are not validated. middleBrick’s Input Validation and Unsafe Consumption checks exercise these endpoints with malformed and over-permissive inputs to detect filter bypasses.

Mongodb-Specific Remediation in Feathersjs — concrete code fixes

Remediation centers on enforcing ownership and tenant scoping, validating and sanitizing inputs, and protecting sensitive fields from unauthorized updates. Always scope queries with the requesting user’s ID or tenant identifier, and use Mongodb query operators to ensure only intended fields are updated.

1) Scope find and get operations to the requesting user. For profile services, include the user ID in the filter:

// Safe find scoped to the authenticated user
app.service('profiles').find({
  query: {
    userId: params.account.userId,
    $limit: 10,
    $skip: 0
  }
});

2) Enforce ownership in before hooks for get, update, and patch. Reject if the target ID does not match the user’s context:

app.hooks({
  before: {
    async get(id, params) {
      if (!id || !params.account || id !== params.account.userId) {
        throw new Error('Not found');
      }
      return id;
    },
    async patch(id, data, params) {
      // Ensure updates only apply to the user’s own document
      if (id !== params.account.userId) {
        throw new Error('Unauthorized');
      }
      // Prevent mass assignment on sensitive fields
      if (data.role !== undefined || data.isAdmin !== undefined) {
        throw new Error('Cannot modify role or admin status');
      }
      return id;
    }
  }
});

3) Use $set for patch to avoid overwriting immutable fields, and explicitly allow only permitted fields:

const allowedPatchFields = ['displayName', 'bio', 'avatarUrl'];

app.hooks({
  before: {
    async patch(id, data, params) {
      if (id !== params.account.userId) {
        throw new Error('Unauthorized');
      }
      // Remove any non-allowed fields to prevent mass assignment
      const patchData = {};
      allowedPatchFields.forEach((field) => {
        if (data[field] !== undefined) {
          patchData[field] = data[field];
        }
      });
      // Return a safe update descriptor for the service layer
      return { $set: patchData };
    }
  }
});

4) When using $in filters, validate each element and scope to the user:

// Safe usage of $in with user-controlled input
const allowedIds = Array.isArray(req.query.ids) ? req.query.ids : [];
const safeIds = allowedIds.filter((id) => typeof id === 'string' && id.length <= 128);

app.service('messages').find({
  query: {
    userId: params.account.userId,
    _id: { $in: safeIds },
    $limit: 20
  }
});

5) For operations that must run with elevated privileges (e.g., admin scripts), use a separate service with strict input validation and never expose them to unauthenticated or user-controlled routes. middleBrick’s BFLA/Privilege Escalation and Authentication checks will highlight routes that perform sensitive actions without adequate guards.

These patterns align with OWASP API Top 10 A01:2023 and map to compliance frameworks checked by middleBrick, such as PCI-DSS and SOC2. By combining scoped queries, hook-level authorization, and strict field validation, you reduce the risk of integrity failures when using FeathersJS with Mongodb.

Frequently Asked Questions

How does middleBrick detect integrity failures in FeathersJS with Mongodb?
middleBrick runs unauthenticated checks that modify identifiers and inspect whether the API enforces ownership and field-level authorization. It probes endpoints with altered IDs and patch payloads to see if records outside the user’s scope are returned or modified, and whether sensitive properties like role can be changed.
Can I rely on middleBrick to fix these issues automatically?
middleBird detects and reports findings with remediation guidance; it does not fix, patch, block, or remediate. Developers should implement scoped queries, hook-level authorization, and field validation based on the reported guidance.