HIGH crlf injectionfeathersjsapi keys

Crlf Injection in Feathersjs with Api Keys

Crlf Injection in Feathersjs with Api Keys — how this specific combination creates or exposes the vulnerability

Crlf Injection occurs when an attacker can inject CRLF sequences (%0D%0A or \r\n) into a header or control part of an HTTP message. In Feathersjs applications that use Api Keys for authentication, this becomes a concern when user-controlled input is reflected in HTTP headers or when the framework constructs dynamic header values without sanitization. Feathersjs is a framework-agnostic REST and real-time layer; it does not enforce header validation by default. If an Api Key is accepted from a request header or query parameter and then forwarded into downstream service calls or reflected in responses, an attacker may embed \r\n sequences to split headers and inject malicious ones, such as Set-Cookie or Location, leading to session fixation or open redirects.

For example, consider a Feathers service that accepts an Api Key via a custom header X-API-Key and uses that key to call a backend service. If the application directly concatenates the header value into another HTTP request without validation, an attacker could supply a key like validkey%0D%0ASet-Cookie:%20session=attacker. This causes the downstream service to interpret the injected CRLF as a new header, potentially overriding intended security controls. Even when Api Keys are validated against a store, the injection occurs before validation logic can sanitize or reject malformed input, allowing the attacker to manipulate the protocol parsing on the server or an intermediary component.

The risk is compounded when Feathersjs is used in a microservice architecture where services chain calls using headers. An attacker exploiting Crlf Injection in this context can manipulate routing, inject cookies, or perform cache poisoning. Because Feathersjs does not inherently sanitize headers, developers must treat any user-supplied data that reaches HTTP headers as untrusted. MiddleBrick scans detect such patterns by correlating API spec definitions with runtime behavior, identifying endpoints where header values derived from inputs are not strictly validated before use.

Api Keys-Specific Remediation in Feathersjs — concrete code fixes

Remediation focuses on strict validation and sanitization of any data used in HTTP headers, especially when Api Keys are involved. Never directly forward user input into header values. Instead, treat Api Keys as opaque credentials, validate them against a secure store, and avoid reflecting them in responses or downstream headers. Use explicit allowlists for header values and enforce strict parsing rules.

Below are concrete code examples for secure Feathersjs services using Api Keys.

1. Validate and use Api Keys without reflection

Do not echo the Api Key into headers or responses. Authenticate the key, then proceed with the request.

// src/services/secure-api-key/secure-api-key.service.js
const crypto = require('crypto');

// Example in-memory store; use a secure vault in production
const VALID_API_KEYS = new Set([
  '2c3f8a1b7e9d4a6f8c0b3e2d1a4f5c6b',
  'a1b2c3d4e5f678901234567890abcdef'
]);

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

  const service = app.service('secure-api-key');

  service.hooks({
    before: {
      all: [async context => {
        const apiKey = context.params.headers['x-api-key'];
        if (!apiKey || !VALID_API_KEYS.has(apiKey.trim())) {
          throw new app.errors.NotAuthenticated('Invalid Api Key');
        }
        // Do not set or forward the raw key in headers
        context.params.headers['x-api-key'] = undefined;
        // Optionally attach a normalized principal for downstream use
        context.params.user = { apiKeyHash: crypto.createHash('sha256').update(apiKey).digest('hex') };
      }]
    },
    after: {
      all: [context => {
        // Ensure no sensitive keys leak in responses
        delete context.result.apiKey;
        return context;
      }]
    }
  });
};

2. Sanitize any user input used in headers before outbound calls

If your Feathers service makes HTTP requests to other services, sanitize any user-controlled data that could reach headers.

// src/services/outbound-request/outbound-request.service.js
const axios = require('axios');
const { sanitizeCrlf } = require('../../utils/header-sanitizer');

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

  app.use('outbound-request', {
    async find(params) {
      const userSuppliedHeader = params.query.headerValue;
      const safeHeaderValue = sanitizeCrlf(userSuppliedHeader);

      try {
        const response = await axios.get('https://downstream.example.com/api', {
          headers: {
            'X-Custom-Header': safeHeaderValue
          },
          timeout: 5000
        });
        return { data: response.data };
      } catch (error) {
        throw new app.errors.GeneralError('Request failed', { cause: error });
      }
    }
  });
};

// utils/header-sanitizer.js
function sanitizeCrlf(value) {
  if (typeof value !== 'string') return value;
  // Remove CRLF sequences and trim
  return value.replace(/[\r\n]+/g, '').trim();
}

module.exports = { sanitizeCrlf };

3. Middleware-level header validation

\n

Add a global hook to reject headers containing CRLF across all services.

// src/hooks/validate-headers.hook.js
function validateHeaders(context) {
  const headers = context.params.headers || {};
  for (const [key, value] of Object.entries(headers)) {
    if (typeof value === 'string' && /[\r\n]/.test(value)) {
      throw new context.app.errors.BadRequest('Header contains invalid characters');
    }
  }
  return context;
}

module.exports = function () {
  return {
    before: [validateHeaders]
 ;
};

Frequently Asked Questions

Can Crlf Injection in Feathersjs with Api Keys be exploited through query parameters?
Yes, if an Api Key is passed via query parameters and later used in headers without sanitization, an attacker can inject CRLF sequences. Always validate and sanitize inputs before using them in HTTP headers, regardless of the source.
Does MiddleBrick detect Crlf Injection patterns in Feathersjs APIs using Api Keys?
MiddleBrick scans API endpoints and correlates spec definitions with runtime behavior to identify places where user input may reach HTTP headers. It flags patterns where Api Key values are reflected or used in header construction without proper sanitization.