HIGH denial of servicefeathersjscockroachdb

Denial Of Service in Feathersjs with Cockroachdb

Denial Of Service in Feathersjs with Cockroachdb — how this specific combination creates or exposes the vulnerability

FeathersJS is a framework for real-time APIs that relies on service abstractions and hooks. When FeathersJS connects to CockroachDB, a distributed SQL database, certain patterns in service configuration, query construction, and hook logic can amplify resource exhaustion and availability risks.

One common scenario involves unparameterized database queries where filters are constructed from user input without validation or bounds. If a client sends a query that lacks pagination or requests an unbounded result set, FeathersJS may generate a CockroachDB query that returns a very large dataset, consuming significant server memory and network bandwidth. In distributed deployments, large scans can increase latency across nodes and contribute to node timeouts.

Long-running or poorly optimized queries can hold connections and threads, especially when connection pooling is not carefully tuned. FeathersJS applications that do not enforce request timeouts or cancellation may allow a single slow CockroachDB query to block event-loop processing for other requests, creating a denial-of-service condition under load.

Another vector arises from real-time channels. FeathersJS enables event-based communication; if a channel broadcasts large result sets or streams high-frequency updates to many connected clients, the cumulative bandwidth and CPU usage on both the application and CockroachDB can spike. Without rate limiting or message-size controls, an attacker could trigger excessive notifications or subscribe to expensive queries, amplifying resource consumption.

Schema design also plays a role. Tables without appropriate indexes can cause CockroachDB to perform full table scans, which are expensive in distributed systems. If FeathersJS services expose endpoints that filter on non-indexed columns, each request may trigger costly scans that degrade performance for all users, effectively turning logical design choices into availability risks.

Finally, error handling that exposes raw database messages or stack traces can aid reconnaissance. An attacker observing detailed CockroachDB errors may infer contention patterns or node health, enabling more targeted stress or probing attacks that precede denial-of-service attempts.

Cockroachdb-Specific Remediation in Feathersjs — concrete code fixes

Mitigation focuses on query constraints, timeouts, and resource controls. Always enforce pagination and limit result sizes for endpoints that could return many rows.

// src/services/users/users.service.js
const { Service } = require('feathersjs');

class UsersService {
  constructor(options) {
    this.options = options || {};
  }

  async find(params) {
    const { $limit = 50, $skip = 0, $sort = 'createdAt_DESC' } = params.query || {};
    const client = params.app.get('cockroachdb-client');

    const parsedLimit = Math.min(Math.max(parseInt($limit, 10), 1), 100);
    const parsedSkip = Math.max(parseInt($skip, 10) || 0, 0);

    const query = {
      select: ['id', 'email', 'name', 'status'],
      from: 'users',
      where: params.query.filter || undefined,
      order: $sort ? $sort.split(',') : ['createdAt_DESC'],
      limit: parsedLimit,
      offset: parsedSkip,
      timeout: 10000
    };

    const result = await client.query(query);
    const total = await client.query({ select: ['COUNT(*) as total'], from: 'users', where: params.query.filter || undefined, timeout: 10000 });

    return {
      total: total[0]?.total || 0,
      limit: parsedLimit,
      skip: parsedSkip,
      data: result
    };
  }
}

module.exports = function () {
  const app = this;
  const client = app.get('cockroachdb-client');

  app.use('/users', new UsersService({
    app,
    model: client
  }));

  const usersService = app.service('/users');
  usersService.hooks({
    before: {
      all: [
        async context => {
          if (context.params.query && context.params.query.$limit && parseInt(context.params.query.$limit, 10) > 1000) {
            throw new Error('Request limit exceeds allowed maximum');
          }
          return context;
        }
      ]
    }
  });
};

This example enforces a configurable page size, validates numeric bounds, sets statement timeouts, and avoids SELECT * by specifying columns. The timeout option helps prevent hung queries from exhausting connection resources.

For real-time channels, apply message-size limits and rate limiting on event emissions.

// src/channels/index.js
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');

const app = feathers();
app.configure(express.rest());
app.configure(socketio());

app.use('/messages', {
  async create(data, params) {
    const MAX_EVENTS_PER_MINUTE = 30;
    const userEvents = await params.app.get('rate-limiter').check(params.user.id, MAX_EVENTS_PER_MINUTE);
    if (!userEvents) {
      throw new Error('Rate limit exceeded');
    }
    // Validate and sanitize payload to avoid large or malicious messages
    if (data.content && data.content.length > 10000) {
      throw new Error('Message too large');
    }
    return data;
  }
});

// Protect real-time channels with size and rate checks
app.channel('messages').join(async (connection, channel) => {
  const userChannels = await channel.send({ type: 'user_channels', channels: ['public'] });
  return userChannels;
});

Ensure CockroachDB indexes exist on commonly filtered columns. For example, an index on (status, createdAt) supports efficient range queries used by paginated endpoints.

-- CockroachDB SQL to create an index used by FeathersJS queries
CREATE INDEX IF NOT EXISTS idx_users_status_createdat ON users (status, created_at);

-- Verify query plan uses the index
EXPLAIN (VERBOSE) SELECT id, email, name FROM users WHERE status = 'active' ORDER BY created_at DESC LIMIT 50;

Use connection pooling with sensible settings to avoid exhausting database connections. Configure timeouts at both the ORM/driver level and the FeathersJS service layer to bound request duration.

middleBrick can scan an unauthenticated FeathersJS endpoint exposed to CockroachDB to surface DoSS indicators such as missing pagination, missing timeouts, and inefficient query patterns. The CLI and Web Dashboard provide prioritized findings with remediation guidance, and the GitHub Action can fail builds if risk thresholds are exceeded.

Related CWEs: resourceConsumption

CWE IDNameSeverity
CWE-400Uncontrolled Resource Consumption HIGH
CWE-770Allocation of Resources Without Limits MEDIUM
CWE-799Improper Control of Interaction Frequency MEDIUM
CWE-835Infinite Loop HIGH
CWE-1050Excessive Platform Resource Consumption MEDIUM

Frequently Asked Questions

Can middleBrick fix DoS issues in FeathersJS services automatically?
No. middleBrick detects and reports potential denial-of-service patterns such as missing pagination, missing timeouts, and large query risks. It provides remediation guidance, but developers must apply the fixes manually in the FeathersJS service code and database configuration.
How does middleBrick handle CockroachDB-specific scan risks?
middleBrick performs black-box scanning against the unauthenticated attack surface of a FeathersJS API, including SQL query behavior inferred from responses. It does not modify the database or require credentials, and findings reference observable patterns like missing bounds on $limit, missing indexes, and missing timeouts that can contribute to resource exhaustion.