HIGH api rate abusefeathersjsapi keys

Api Rate Abuse in Feathersjs with Api Keys

Api Rate Abuse in Feathersjs with Api Keys — how this specific combination creates or exposes the vulnerability

FeathersJS is a minimal, extensible framework for creating JavaScript APIs with services and hooks. When API keys are used for identification but not paired with explicit rate-limiting, the API exposes endpoints to rate abuse even though callers present a credential. An API key is a bearer token; if it is leaked or shared, any holder can make unlimited requests until the key is rotated. Attackers can automate enumeration, brute-force secondary identifiers (such as user IDs), or amplify resource consumption by invoking service methods that perform heavy computation or database queries. Because FeathersJS services map closely to REST-like routes, abuse often targets collection GETs, search endpoints, or custom methods that lack per-key or per-user throttling.

The risk is compounded when keys are issued at a global scope rather than per-user or per-role. A compromised key effectively becomes a universal ticket for unauthenticated-style abuse, because the service may still enforce only ownership checks (e.g., BOLA/IDOR) without considering request volume. For example, an endpoint like /v1/messages?userId=123 might verify that the API key is allowed to see messages for that user, but without rate limits it can be polled to infer data availability or to exhaust backend connections. MiddleBrick’s 12 checks run in parallel and include Rate Limiting and Authentication, which surface these gaps by correlating unauthenticated attack surface signals with API key usage patterns.

Real-world attack patterns mirror OWASP API Top 10 #2: Broken Object Level Authorization and #4: Unrestricted Resource Consumption. Consider a custom Feathers hook that does not enforce quotas; an attacker can send many requests with a valid API key to enumerate IDs via BOLA logic or to trigger expensive operations such as reports or exports. If the service uses pagination without strict limits, a single call can pull large datasets, leading to data exposure and increased load. Even when keys are rotated, without centralized rate enforcement the abuse continues until detection. MiddleBrick’s LLM/AI Security checks do not apply here, but its Rate Limiting and Authentication tests highlight scenarios where keys are accepted but misuse is possible.

Api Keys-Specific Remediation in Feathersjs — concrete code fixes

Remediation centers on binding API keys to identities and enforcing per-key or per-user rate limits. Do not rely on key secrecy alone; treat keys as opaque identifiers and apply throttling at the service or hook level. Below are syntactically correct FeathersJS snippets that demonstrate a robust pattern using a custom hook.

// src/hooks/rate-limit-by-key.js
const { RateLimiterMemory } = require('rate-limiter-flexible');

// Configure limits: 100 requests per 60 seconds per API key
const rateLimiter = new RateLimiterMemory({
  points: 100,
  duration: 60,
});

module.exports = function rateLimitByKey(options = {}) {
  return async context => {
    // Assume API key is passed in a header; adjust to your auth scheme
    const key = context.params.headers['x-api-key'];
    if (!key) {
      throw new Error('API key missing');
    }

    try {
      await rateLimiter.consume(key);
    } catch (rateLimitError) {
      const ms = rateLimitError.msBeforeNext / 1000;
      throw new Error(`Rate limit exceeded. Try again in ${ms} seconds.`);
    }

    return context;
  };
};

Register the hook in your service configuration so it runs before any service method:

// src/services/messages/messages.service.js
const rateLimitByKey = require('../hooks/rate-limit-by-key');

module.exports = function (app) {
  const options = {
    name: 'messages',
    paginate: { default: 10, max: 50 },
  };

  // Initialize service with options
  app.use('/messages', require('feathers-sequelize')(options));
  const service = app.service('messages');

  // Apply rate-limiting hook globally for this service
  service.hooks({
    before: {
      all: [rateLimitByKey()],
    },
  });
};

For multi-tenant scenarios, scope limits by user identifier derived from the key, ensuring that shared keys do not allow a single user to monopolize resources:

// src/hooks/rate-limit-by-user.js
const { RateLimiterRedis } = require('rate-limiter-flexible');
const Redis = require('ioredis');

const client = new Redis(process.env.REDIS_URL);
const rateLimiter = new RateLimiterRedis({
  storeClient: client,
  points: 300,
  duration: 60,
});

module.exports = function rateLimitByUser(options = {}) {
  return async context => {
    const { user } = context.params.account;
    if (!user) {
      throw new Error('User not resolved');
    }
    try {
      await rateLimiter.consume(user.id);
    } catch (error) {
      const ms = error.msBeforeNext || 60_000;
      throw new Error(`User rate limit exceeded. Retry after ${Math.ceil(ms / 1000)}s`);
    }
    return context;
  };
};

Combine these hooks with key-to-user mapping logic in your authentication layer to ensure each key is associated with a stable identity. Additionally, set reasonable pagination caps and monitor outlier consumption via logs. MiddleBrick’s dashboard can track score changes over time, while the CLI allows you to script scans and fail CI/CD pipelines if regressions appear.

Frequently Asked Questions

How can I verify that rate limits are enforced per API key in FeathersJS?
Send a series of requests with a valid API key and assert that responses return HTTP 429 after the configured threshold. Inspect logs to confirm that limits are scoped to the key and that shared keys do not bypass per-user caps.
Does MiddleBrick detect rate-limiting misconfigurations tied to API keys?
Yes. MiddleBrick’s parallel Rate Limiting check flags endpoints where authentication (including API key presence) exists without corresponding throttling, and it correlates findings with Authentication and BOLA/IDOR checks to highlight abuse risks.