HIGH broken authenticationfeathersjscockroachdb

Broken Authentication in Feathersjs with Cockroachdb

Broken Authentication in Feathersjs with Cockroachdb — how this specific combination creates or exposes the vulnerability

Broken Authentication in a Feathersjs service backed by Cockroachdb typically arises from a mismatch between Feathersjs application logic and database-side controls. Feathersjs is a framework that favors minimal built-in authentication; it relies on explicit configuration of authentication handlers and hooks. When authentication is misconfigured or omitted, an attacker can call service methods directly without a valid subject or token. Because Cockroachdb is strongly consistent and supports granular role-based privileges, the database can enforce constraints, but those constraints must be correctly mapped to Feathersjs hooks and services.

One common pattern is a Feathersjs service that connects to Cockroachdb with a connection pool using a role that has broader privileges than intended. If the service does not validate ownership or scope per request, horizontal privilege escalation becomes feasible. For example, a /users/:id endpoint that does not enforce that the requesting user can only access their own row allows BOLA/IDOR regardless of database-level row policies. Attackers may also probe unauthenticated endpoints; Feathersjs allows service registration without authentication, and if those services interact with Cockroachdb without applying tenant or user filters, data exposure occurs.

Another vector is credential handling. Feathersjs can integrate with authentication libraries such as @feathersjs/authentication-local, but if passwords are stored weakly in Cockroachdb (e.g., plaintext or with a weak hash), authentication is broken regardless of transport security. Attackers may leverage common weaknesses like missing rate limiting on login services to perform credential stuffing. Because Cockroachdb provides ACID guarantees, brute-force or timing-based attacks can be more predictable if the server’s response times leak validation state.

Middleware and hooks are central in Feathersjs. If before-hooks do not normalize identifiers (e.g., resolving a user ID from a JWT and attaching it to the params), subsequent hooks or the service handler may inadvertently operate on the wrong subject. With Cockroachdb, this can lead to operations being applied to rows the user should not touch. Insecure consumption patterns, such as passing raw query parameters directly into Knex or Sequelize-style query builders without validation, enable injection or privilege escalation.

Finally, configuration details matter. If the Feathersjs application connects to Cockroachdb using a service account with high privileges and does not enforce row-level security at the application layer, a single compromised endpoint can lead to wide data exposure. Proper remediation requires coordinated changes in the Feathersjs service configuration, hook implementation, and Cockroachdb role grants and policies to ensure least privilege and subject-level enforcement.

Cockroachdb-Specific Remediation in Feathersjs — concrete code fixes

Remediation centers on tightening authentication checks, enforcing ownership at the database level, and ensuring least-privilege database roles. Below are concrete, syntactically correct examples for a Feathersjs service interacting with Cockroachdb using Knex-style query building.

  • Define a restricted Cockroachdb role for the application user and grant minimal privileges:
-- In Cockroachdb, create a role with SELECT/INSERT/UPDATE limited to necessary columns
grant select, insert, update (id, email, hashed_password, tenant_id) on users to app_reader_writer;
revoke delete on users from app_reader_writer;
-- Ensure row-level security via application-side checks; Cockroachdb does not enforce RLS natively in all deployments
  • Feathersjs service configuration with authentication and hooks that enforce ownership:
const { AuthenticationService } = require('@feathersjs/authentication');
const { expressOauth } = require('@feathersjs/authentication-oauth');
const { iff, isProvider } = require('feathers-hooks-common');

app.use('/users', new AuthenticationService({
  entity: 'user',
  service: app.service('users'),
  paginate: { default: 25, max: 50 }
}));

app.service('users').hooks({
  before: {
    all: [ auth.hooks.authenticate(['jwt']) ],
    find: [ (context) => {
      // Ensure queries are scoped to the authenticated subject
      if (context.params.user) {
        context.params.query.userId = context.params.user.id;
        // Optionally restrict by tenant if applicable
        if (context.params.user.tenantId) {
          context.params.query.tenantId = context.params.user.tenantId;
        }
      }
      return context;
    }],
    get: [ (context) => {
      // Enforce that users can only retrieve their own profile
      const userId = context.params.user.id;
      context.params.query = { id: userId };
      return context;
    }],
    create: [ (context) => {
      // Set the subject on creation if not provided
      if (context.params.user) {
        context.data.userId = context.params.user.id;
      }
      return context;
    }],
    update: [ (context) => {
      // Prevent updating other users’ records
      const userId = context.params.user.id;
      if (context.id !== undefined && context.id !== userId) {
        throw new Error('Forbidden: cannot update other user records');
      }
      context.params.query = { id: userId };
      return context;
    }],
    patch: [ (context) => {
      // Apply ownership filter for partial updates
      const userId = context.params.user.id;
      context.params.query = { id: userId };
      return context;
    }]
  },
  after: [ iffy(isProvider('external'), sanitizePublic) ],
});
  • Explicit input validation and query scoping in a custom hook to prevent unsafe consumption:
const sanitizeQuery = (context) => {
  const allowedFields = ['email', 'profile'];
  const query = context.params.query || {};
  // Remove potentially dangerous keys
  delete query.$where;
  delete query.$customData;
  // Whitelist fields
  if (query.select) {
    const selectFields = query.select.split(',').filter(f => allowedFields.includes(f.trim()));
    query.select = selectFields.join(',');
  }
  // Ensure tenant or user scope is applied when available
  if (context.params.user && !query.userId) {
    query.userId = context.params.user.id;
  }
  context.params.query = query;
  return context;
};
  • Example of a login route that enforces rate limiting and secure password comparison using the Feathersjs authentication service with Cockroachdb-backed entities:
const local = require('@feathersjs/authentication-local').authentication;
app.use('/login', local({
  service: app.service('users'),
  usernameField: 'email',
  passwordField: 'password'
}));
// Ensure the users service uses hashed passwords and a strong hash like bcrypt
app.service('users').hooks({
  before: {
    create: [ (context) => {
      // Assume a hook hashes the password before storage
      if (context.data.password) {
        context.data.password = hashPassword(context.data.password);
      }
      return context;
    }]
  }
});

These examples emphasize that broken authentication is not only about transport security but also about proper scoping, subject validation, and least-privilege database access patterns. MiddleBrick scans can surface misconfigured authentication flows and unsafe consumption patterns; its findings map to frameworks such as OWASP API Top 10 and compliance regimes like SOC2 and GDPR. For continuous assurance, the Pro plan enables scheduled scans and alerts, while the CLI allows you to integrate checks into scripts and pipelines.

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

How does middleBrick detect broken authentication in Feathersjs services?
middleBrick runs unauthenticated scans and authenticated probes where configured. It checks for missing authentication on sensitive endpoints, verifies that subject-level scoping is enforced, and inspects credential storage practices. Findings highlight gaps such as missing hooks, overly permissive database roles, or unsafe query construction that can lead to authentication bypass or horizontal escalation.
Can middleBrick fix broken authentication automatically?
middleBrick detects and reports issues with remediation guidance; it does not automatically patch code or reconfigure databases. Use the CLI to integrate checks into your workflow and the Web Dashboard to track scores and findings over time.