HIGH identification failuresfeathersjsfirestore

Identification Failures in Feathersjs with Firestore

Identification Failures in Feathersjs with Firestore — how this specific combination creates or exposes the vulnerability

Identification failures occur when an API incorrectly identifies or trusts the identity of the requester, allowing one user to act as another. In a Feathersjs application using Cloud Firestore as the backing store, this typically arises from a mismatch between authorization logic and Firestore security rules, or from incomplete verification of request context before data access is granted.

Feathersjs uses a service-oriented architecture where each service can define its own authentication and hooks. If a service does not enforce strict identity checks and relies only on the presence of a payload or token, an attacker can manipulate identifiers such as user IDs in request parameters or body. Because Firestore rules may be scoped to documents by ID, an incorrectly trusted client-supplied ID can lead to reading or modifying records that belong to another user.

For example, a Feathersjs service for user profiles might accept a URL like /users/{userId} and directly forward { userId } to a Firestore get call without verifying that the authenticated subject matches { userId }. Firestore security rules that assume the request.auth.uid is always aligned with the document path can be bypassed if the service layer does not enforce this invariant. Real-world findings from middleBrick scans show this class of flaw often combines with insufficient input validation, enabling IDOR via tampered identifiers, and can expose personal data or allow privilege escalation when Firestore rules are misconfigured to trust client-supplied document IDs.

Additionally, Firestore’s flexible querying can inadvertently support identification failures if queries use client-supplied filters without validating ownership. A Feathersjs hook that builds a where clause using unchecked params can allow an attacker to enumerate or retrieve other users’ documents. middleBrick’s BOLA/IDOR and Property Authorization checks are designed to detect these patterns by correlating runtime requests with OpenAPI definitions and Firestore rule expectations, highlighting where identification is not strictly enforced.

Because Firestore operates with rules rather than traditional RBAC checks at the application layer, developers must ensure that every service method validates auth context against document paths. middleBrick’s OpenAPI/Swagger spec analysis, including full $ref resolution, helps surface mismatches between declared parameters and actual security expectations, reducing the risk of identification failures in production.

Firestore-Specific Remediation in Feathersjs — concrete code fixes

Remediation focuses on ensuring that the authenticated subject is explicitly verified before any Firestore read or write, and that Firestore security rules reinforce this check. The following patterns demonstrate secure approaches for Feathersjs services using Firestore.

1. Explicit UID verification in service hooks

Always resolve the authenticated user from the Feathers request context and compare it to any user-supplied identifier before constructing a Firestore path or query.

// src/services/users/users.class.js
const { Service } = require('feathersjs');
const admin = require('firebase-admin');

class UserService extends Service {
  async find(params) {
    const { user } = params; // Authenticated user from Feathers auth
    if (!user || !user.uid) {
      throw new Error('Unauthenticated');
    }
    // Only allow access to the requesting user's document
    const docRef = admin.firestore().collection('users').doc(user.uid);
    const snap = await docRef.get();
    if (!snap.exists) {
      throw new Error('Not found');
    }
    return snap.data();
  }

  async get(id, params) {
    const { user } = params;
    if (user.uid !== id) {
      throw new Error('Forbidden: mismatched user ID');
    }
    const docRef = admin.firestore().collection('users').doc(id);
    const snap = await docRef.get();
    if (!snap.exists) {
      throw new Error('Not found');
    }
    return snap.data();
  }
}

2. Firestore security rules aligned with Feathers auth

Rules should scope writes and reads to documents that match request.auth.uid and reject client-supplied IDs for sensitive operations.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
    // Avoid allowing writes where document ID is client-supplied without ownership check
    match /profiles/{docId=**} {
      allow write: if request.auth != null && request.auth.uid == request.resource.data.userId;
      allow read: if request.auth != null && request.auth.uid == docId;
    }
  }
}

3. Parameter sanitization and query constraints

Never directly use raw query parameters to build Firestore queries. Validate and bind them to the authenticated user.

// src/services/records/records.class.js
class RecordService extends Service {
  async find(params) {
    const { user } = params;
    const collection = admin.firestore().collection('records');
    const query = collection.where('ownerId', '==', user.uid).limit(100);
    const snap = await query.get();
    return snap.docs.map(d => ({ id: d.id, ...d.data() }));
  }
}

4. Use Feathers hooks to inject auth context

Centralize authentication checks in before hooks to avoid repeating logic across services.

// src/hooks/authentication.js
const authenticate = async context => {
  const { accessToken } = context.params.headers || {};
  if (!accessToken) {
    throw new Error('Unauthorized');
  }
  try {
    const decoded = await admin.auth().verifyIdToken(accessToken);
    context.params.user = { uid: decoded.uid };
  } catch (error) {
    throw new Error('Invalid token');
  }
  return context;
};

module.exports = { authenticate };

5. Combine with middleBrick checks

Use the middleBrick CLI to validate that your Firestore rules and Feathers hooks align with expected security posture. The BOLA/IDOR and Property Authorization checks can highlight mismatches between declared parameters and runtime access patterns, complementing the fixes above.

Frequently Asked Questions

Can Firestore security rules alone prevent identification failures in Feathersjs?
Firestore rules are necessary but not sufficient on their own. Rules must be paired with server-side validation in Feathers hooks to ensure the authenticated subject matches the intended resource before any database operation.
How does middleBrick help detect identification failures with Firestore?
middleBrick runs BOLA/IDOR and Property Authorization checks that correlate OpenAPI definitions with runtime behavior, surfacing cases where client-supplied identifiers are trusted without proper auth verification against Firestore rules.