HIGH integrity failuresfeathersjs

Integrity Failures in Feathersjs

How Integrity Failures Manifests in Feathersjs

Integrity Failures in Feathersjs applications occur when users can manipulate data they shouldn't have access to, typically through IDOR (Insecure Direct Object Reference) vulnerabilities. In Feathersjs, this commonly manifests through service operations where the user ID is either missing from queries or improperly validated.

The most frequent pattern involves service methods like find, get, update, and patch where the user can specify arbitrary IDs in query parameters. For example, a REST endpoint like /messages/123 might allow any authenticated user to retrieve or modify message 123, regardless of whether they own it.

// Vulnerable Feathersjs service method
class MessageService {
  async get(id, params) {
    // No user ID validation - any user can access any message
    return await this._get(id, params);
  }

  async update(id, data, params) {
    // No ownership check - user can update any message
    return await this._patch(id, data, params);
  }
}

Another common manifestation occurs with query parameter manipulation. Feathersjs services accept query objects that can be manipulated to bypass authorization. A user might modify the userId field in a query to access another user's data:

// Vulnerable query manipulation
const params = {
  query: {
    userId: 999 // User manually changes to access another user's data
  }
};

Feathersjs's real-time features also introduce integrity risks. When using app.channel() without proper filtering, users might receive events about data they shouldn't see:

// Vulnerable real-time channel
app.service('messages').publish((data, context) => {
  // Broadcasts to all connected clients - no filtering
  return app.channel("anonymous");
});

Property authorization failures are particularly problematic in Feathersjs. The framework's flexible data model means that sensitive properties might be exposed through service methods without proper access controls:

// Vulnerable property exposure
class UserService {
  async find(params) {
    // Returns all user properties including sensitive data
    return await this._find(params);
  }
}

Feathersjs-Specific Detection

Detecting Integrity Failures in Feathersjs requires examining both the service code and runtime behavior. Start by auditing your service methods for missing authorization checks. Look for service methods that accept IDs or query parameters without validating the requesting user's permissions.

middleBrick's black-box scanning approach is particularly effective for Feathersjs applications. The scanner tests unauthenticated attack surfaces by sending requests with manipulated IDs and query parameters to identify BOLA/IDOR vulnerabilities. For a Feathersjs API at https://api.example.com, middleBrick would:

  1. Map the API surface by discovering all available endpoints
  2. Test each endpoint with manipulated IDs (incrementing numbers, common IDOR patterns)
  3. Analyze responses for data leakage or unauthorized access
  4. Check for missing authentication requirements on sensitive endpoints
  5. Validate property authorization by requesting data with different user contexts

middleBrick's Feathersjs-specific detection includes checking for common patterns like:

// What middleBrick scans for:
// 1. Missing user ID in service method calls
// 2. Unfiltered query parameters
// 3. Broad real-time channels without user filtering
// 4. Exposed sensitive properties in service responses

Manual code review should focus on Feathersjs's authentication hooks and service methods. Use middleBrick's CLI to scan your API during development:

npm install -g middlebrick
middlebrick scan https://api.example.com/messages

For continuous security, integrate middleBrick into your Feathersjs CI/CD pipeline using the GitHub Action. This ensures new endpoints are automatically scanned for integrity failures before deployment:

# .github/workflows/security.yml
name: API Security Scan
on: [push, pull_request]
jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run middleBrick Scan
        uses: middlebrick/middlebrick-action@v1
        with:
          target: https://staging-api.example.com
          fail-on-severity: high

Feathersjs-Specific Remediation

Remediating Integrity Failures in Feathersjs requires implementing proper authorization at the service level. The most effective approach is using Feathersjs's built-in authentication hooks and custom authorization logic.

For basic ownership validation, use the authenticate hook combined with custom logic:

const { authenticate } = require('@feathersjs/authentication').hooks;
const { iff, isProvider, fastJoin } = require('feathers-hooks-common');

class MessageService {
  async get(id, params) {
    // Ensure user can only access their own messages
    const userId = params.user?.id;
    const message = await this._get(id, params);
    
    if (message.userId !== userId) {
      throw new Error('Access denied');
    }
    
    return message;
  }

  async update(id, data, params) {
    const userId = params.user?.id;
    const message = await this._get(id, params);
    
    if (message.userId !== userId) {
      throw new Error('Access denied');
    }
    
    return await this._patch(id, data, params);
  }
}

For more scalable solutions, implement authorization hooks that automatically filter data based on the authenticated user:

const { authenticate } = require('@feathersjs/authentication').hooks;
const { iff, isProvider, fastJoin } = require('feathers-hooks-common');

const userFilter = () => context => {
  const { type, params, method } = context;
  
  if (type === 'before' && params.user) {
    context.params.query = {
      ...context.params.query,
      userId: params.user.id
    };
  }
};

module.exports = {
  before: {
    all: [authenticate('jwt'), userFilter()],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  }
};

Property authorization can be handled using Feathersjs's population and serialization features:

const { fastJoin } = require('feathers-hooks-common');

const protectedProperties = {
  joins: {
    excludeSensitive: () => async (recs, context) => {
      if (Array.isArray(recs)) {
        recs.forEach(rec => {
          if (rec.user) {
            delete rec.user.password;
            delete rec.user.sensitiveData;
          }
        });
      }
    }
  }
};

module.exports = {
  before: {
    all: [authenticate('jwt')]
  },
  after: {
    all: [fastJoin(protectedProperties)]
  }
};

For real-time integrity, implement proper channel filtering:

app.service('messages').publish((data, context) => {
  // Only send to users who own the data or have permission
  if (data.userId === context.user?.id) {
    return app.channel(`userIds/${context.user.id}`);
  }
  
  // Or return empty channel for unauthorized users
  return app.channel();
});

Frequently Asked Questions

How does middleBrick detect Integrity Failures in Feathersjs APIs?
middleBrick performs black-box scanning by sending requests with manipulated IDs and query parameters to your Feathersjs endpoints. It tests for BOLA/IDOR vulnerabilities by incrementing IDs, modifying query parameters, and checking if users can access data they shouldn't own. The scanner runs 12 security checks in parallel and provides a risk score with specific findings for your Feathersjs application.
Can middleBrick scan my Feathersjs API that uses websockets for real-time features?
Yes, middleBrick can scan REST endpoints that power Feathersjs real-time features. While it doesn't directly test websocket connections, it scans the underlying REST API that the websocket service uses. For comprehensive testing, scan your API's base URL and middleBrick will discover all available endpoints, including those used by real-time features.