HIGH broken access controlfeathersjsjavascript

Broken Access Control in Feathersjs (Javascript)

Broken Access Control in Feathersjs with Javascript — how this specific combination creates or exposes the vulnerability

FeathersJS is a framework for Node.js that exposes services through a consistent API surface, commonly REST and real-time sockets. When access control is improperly enforced, an authenticated user can manipulate requests to access or modify data belonging to other users. This typically occurs when service methods rely on the request context (params) without validating ownership or role.

In JavaScript implementations, developers often pass the authenticated user object (e.g., params.user) into service logic but fail to scope queries to that user. For example, a "messages" service that lists all messages without filtering by params.user.id allows BOLA (Broken Object Level Authorization), a core facet of Broken Access Control. An attacker can send a request with a different user identifier or omit identifiers to enumerate or modify other users' records.

Feathers hooks provide a central place to enforce authorization, yet if hooks are omitted or misconfigured, the service remains exposed. A common mistake is defining a service without a hook that filters records based on the authenticated user. Since JavaScript is dynamically typed, it is easy to accidentally trust params.query.userId supplied by the client, leading to insecure direct object references. The framework's flexibility in chaining hooks and custom methods increases risk if developers do not consistently apply ownership checks across all methods (find, get, create, update, patch, remove).

Real-world attack patterns include changing numeric IDs in URLs or query parameters to access other users' resources, or leveraging administrative roles improperly elevated via modified JWT claims. Without runtime validation that the requesting user owns the target resource, the API silently returns unauthorized data. middleBrick tests these scenarios by submitting modified requests and inspecting whether responses reveal data or functionality that should be restricted, surfacing findings aligned with OWASP API Top 10 Broken Access Control.

Javascript-Specific Remediation in Feathersjs — concrete code fixes

Remediation centers on scoping data access to the authenticated user and validating roles explicitly within service hooks. Always filter records in the before hook using data from params.user rather than trusting client-supplied query fields.

// Safe: scope the find query to the authenticated user's ID
module.exports = function (app) {
  const messages = app.service('messages');
  messages.hooks({
    before: {
      async find(context) {
        // Ensure only the requesting user's messages are returned
        context.params.query.userId = context.params.user.id;
        return context;
      },
      async get(context) {
        // Optional: double-check that the requested ID matches the user
        const message = await app.service('messages').Model.findByPk(context.id);
        if (!message || message.userId !== context.params.user.id) {
          throw new Error('Not found');
        }
        return context;
      }
    }
  });
};

For update and patch operations, avoid allowing the client to set ownership fields. Explicitly remove or ignore fields like userId and role from updates controlled by the client.

// Safe: prevent client-controlled role escalation in patch
module.exports = function (app) {
  const users = app.service('users');
  users.hooks({
    before: {
      async patch(context) {
        // Remove any client-supplied role or userId from the patch data
        delete context.data.userId;
        delete context.data.role;
        // Enforce that the modifier is the same user or an admin
        if (!context.params.user) throw new Error('Unauthenticated');
        // Optionally, restrict updates to self unless admin
        if (!context.params.user.isAdmin && context.id !== context.params.user.id) {
          throw new Error('Forbidden');
        }
        return context;
      }
    }
  });
};

Use role-based checks for administrative endpoints, and prefer comparing IDs directly rather than relying on string roles that can be tampered with. Combine hooks with model-level constraints (unique indexes on user-scoped fields) to reduce the impact of programming errors.

When integrating with authentication libraries, ensure the user object in params.user is populated reliably and not derived from mutable client data. middleBrick’s checks for BOLA/IDOR validate that each endpoint enforces ownership or role constraints, surfacing deviations specific to JavaScript implementations.

Frequently Asked Questions

How does middleBrick detect Broken Access Control in a Feathersjs API?
middleBrick runs unauthenticated checks that modify requests to access resources belonging to other users, inspects whether responses expose data or functionality across tenant boundaries, and verifies that hooks or service logic consistently scope queries to the authenticated user.
Can I rely solely on client-side validation to prevent Broken Access Control in JavaScript Feathersjs services?
No. Client-side validation is easily bypassed. Authorization must be enforced server-side in Feathers hooks by scoping data access to params.user and validating roles before any data operation.