HIGH out of bounds writefeathersjsbasic auth

Out Of Bounds Write in Feathersjs with Basic Auth

Out Of Bounds Write in Feathersjs with Basic Auth — how this specific combination creates or exposes the vulnerability

An Out Of Bounds Write occurs when an API accepts input that causes a service to write data outside intended memory or buffer boundaries. In FeathersJS, this typically manifests through unsafe dynamic assignment or unchecked array/slice operations when processing payloads. When Basic Auth is used, the authentication layer supplies user identity via headers, but does not inherently validate or constrain the structure or size of the request body. This creates a scenario where authenticated (or unauthenticated, if the endpoint is exposed) requests can supply crafted payloads that exploit unchecked numeric indices, string offsets, or buffer-length miscalculations in service logic or underlying libraries.

FeathersJS services often rely on generic hooks and transports (e.g., REST or Socket.io) that merge params.query, params.body, and runtime configuration. If a developer binds incoming data directly to a model or in-memory structure without validating length, type, or bounds, an attacker can provide values that shift write positions beyond allocated memory regions. For example, numeric fields used as array indices or pagination cursors may be coerced into large integers, causing writes to adjacent memory. Because Basic Auth headers are parsed before body validation, an attacker may leverage authenticated sessions to probe endpoints for unchecked mutation operations, increasing the likelihood of successful exploitation in microservice architectures where services chain multiple Feathers hooks.

Consider a Feathers service that accepts a payload specifying an index and a value to update an array stored in process memory or a temporary buffer. Without explicit bounds checks, an attacker authenticated via Basic Auth can supply an index beyond the allocated array length, triggering an out-of-bounds write. In runtime environments, this may lead to corrupted state, unexpected behavior, or potential code execution depending on the language runtime and memory protections. The combination of Basic Auth (which may provide a false sense of access control) and unchecked mutation endpoints amplifies risk because developers might assume authentication equates to safe input handling.

OpenAPI/Swagger specifications can inadvertently encourage these issues when definitions lack explicit constraints on numeric ranges or string lengths. If an endpoint definition describes an integer parameter without minimum/maximum limits, runtime values can overflow fixed buffers. middleBrick’s specification analysis correlates such definitions with runtime behavior, flagging endpoints where user-controlled data influences memory-adjacent operations. This is particularly relevant for endpoints using Basic Auth, where authentication correctness is separated from input validation responsibilities. Attack patterns like CVE-2021-23337, which involved boundary violations in web frameworks, illustrate how unchecked indices enable write primitives. In FeathersJS, similar patterns emerge when services perform direct array mutations or interact with native addons that do not validate bounds.

To detect this class of issues, scanning should examine hooks that perform mutations (e.g., create, update, patch) and verify that all indices, lengths, and offsets are validated against known limits. Payloads that include large integers, negative values, or deeply nested structures should be tested for out-of-bounds behavior. middleBrick’s checks for Input Validation and Unsafe Consumption are designed to surface these risks by correlating spec definitions with observed runtime behavior, including scenarios where Basic Auth headers are present but input constraints are missing.

Basic Auth-Specific Remediation in Feathersjs — concrete code fixes

Remediation focuses on validating and sanitizing all user-supplied data before it influences memory operations, regardless of authentication method. With Basic Auth, you must ensure that identity extraction does not bypass input validation. Below are concrete code examples demonstrating secure practices in FeathersJS.

Example 1: Validating array indices with explicit bounds

Ensure numeric indices are within allowed ranges before using them to mutate arrays. Use a validation hook that checks min/max values and rejects malformed payloads.

// src/hooks/validate-index.hooks.js
const { BadRequest } = require('@feathersjs/errors');

module.exports = function validateIndex(options = {}) {
  return async context => {
    const { index, value } = context.data || {};
    const MAX_INDEX = 1024; // Define a safe upper bound

    if (typeof index !== 'number' || !Number.isInteger(index) || index < 0 || index >= MAX_INDEX) {
      throw new BadRequest('Invalid index: must be an integer between 0 and 1023');
    }

    // Proceed safely
    if (!context.app.get('internalBuffer')) {
      context.app.set('internalBuffer', new Array(MAX_INDEX).fill(null));
    }
    const buffer = context.app.get('internalBuffer');
    buffer[index] = value; // Safe write within bounds

    context.data = { index, value };
    return context;
  };
};

Example 2: Using Feathers validation with custom checks

Leverage feathers-hooks-common validators to enforce constraints on payload fields. Combine with Basic Auth hooks to ensure identity and data integrity are independently verified.

// src/hooks/validate-payload.hooks.js
const { iff, isProvider, preventChanges } = require('feathers-hooks-common');
const { BadRequest } = require('@feathersjs/errors');

const validateArrayPayload = () => async context => {
  const data = context.data || {};
  if (data.items && Array.isArray(data.items)) {
    if (data.items.length === 0 || data.items.length > 500) {
      throw new BadRequest('items must contain between 1 and 500 elements');
    }
    for (const item of data.items) {
      if (typeof item.id !== 'number' || item.id < 0 || item.id >= 10000) {
        throw new BadRequest('item.id must be a non-negative integer less than 10000');
      }
    }
  }
  return context;
};

module.exports = {
  before: {
    all: [iff(isProvider('external'), preventChanges(['internalId']))],
    find: [validateArrayPayload()],
    create: [validateArrayPayload()]
  }
};

Example 3: Securing Basic Auth integration with explicit checks

Basic Auth should be handled by a dedicated hook that extracts credentials without affecting body validation. Ensure hooks run in the correct order: authentication first, then input validation.

// src/hooks/basic-auth.hooks.js
const { BadRequest } = require('@feathersjs/errors');
const { lookup } = require('feathers-authentication-hooks');

module.exports = function basicAuthHook(options) {
  return async context => {
    const authHeader = context.headers.authorization || '';
    if (!authHeader.startsWith('Basic ')) {
      throw new BadRequest('Unauthorized: Basic Auth header required');
    }
    const base64 = authHeader.split(' ')[1];
    const decoded = Buffer.from(base64, 'base64').toString('utf-8');
    const [username, password] = decoded.split(':');

    // Validate credentials (replace with your user verification logic)
    if (!username || !password || username !== 'admin' || password !== 'secure') {
      throw new BadRequest('Invalid credentials');
    }

    // Attach identity to context for downstream hooks
    context.params.user = { username };
    return context;
  };
};

Example 4: Applying hooks to a Feathers service

Compose your service with validation and authentication hooks to enforce bounds and proper credential handling.

// src/services/array-service/array-service.class.js
const { Service } = require('feathersjs');
const { iff, isProvider } = require('feathers-hooks-common');
const validateIndex = require('./hooks/validate-index.hooks');
const basicAuthHook = require('./hooks/basic-auth.hooks');
const validatePayload = require('./hooks/validate-payload.hooks');

class ArrayService extends Service {
  create(data, params) {
    // Ensure bounds checks are enforced via hooks
    return super.create(data, params);
  }

  update(id, data, params) {
    return super.update(id, data, params);
  }
}

module.exports = function initService() {
  const app = this;
  const service = new ArrayService({
    name: 'array',
    async id(value) { return value.id; }
  });

  app.use('/array', service);

  service.hooks([
    { before: { all: [basicAuthHook(), validatePayload()] } },
    { before: { create: [validateIndex()], update: [validateIndex()] } },
    { after: [] }
  ]);
};

These examples illustrate how to combine Basic Auth identity handling with strict input validation to prevent out-of-bounds writes. Always define explicit limits for numeric indices, array sizes, and offsets. Validate on both client and server sides, and use middleware to enforce constraints before mutations occur. middleBrick’s scans can help identify endpoints where such validation is missing, particularly in OpenAPI specs where range constraints are not defined.

Frequently Asked Questions

Can an attacker exploit Out Of Bounds Write if Basic Auth credentials are incorrect?
Yes. Basic Auth may provide a false sense of security because authentication correctness is separate from input validation. Even with invalid credentials, some endpoints may still accept requests if they lack proper access control, and out-of-bounds writes can be triggered by unauthenticated probes if the endpoint is exposed. Always validate input independently of authentication.
How does middleBrick help detect Out Of Bounds Write risks in FeathersJS APIs using Basic Auth?
middleBrick’s OpenAPI/Swagger analysis correlates spec definitions with runtime tests, flagging endpoints where user-controlled data influences operations like array indexing without explicit bounds. Its Input Validation and Unsafe Consumption checks highlight missing constraints in services that use Basic Auth, where authentication headers do not constrain payload structure.