HIGH header injectionfeathersjsdynamodb

Header Injection in Feathersjs with Dynamodb

Header Injection in Feathersjs with Dynamodb — how this specific combination creates or exposes the vulnerability

Header Injection occurs when user-controlled data is reflected into HTTP response headers without validation or sanitization. In a Feathersjs application using Dynamodb as the persistence layer, this typically arises when values from Dynamodb records or query parameters are passed directly into headers such as Location, X-Request-ID, or custom headers. Because Feathersjs services often construct responses from Dynamodb query results, an attacker can supply header-like input (for example, a newline character embedded in a user profile field or an API key) that later becomes part of a header.

The combination of Feathersjs and Dynamodb can expose Header Injection in two primary ways:

  • Unvalidated data from Dynamodb items is used in server logic that sets headers, for example when returning a redirect (302) with a user-controlled Location derived from a Dynamodb attribute.
  • Middleware or hooks in Feathersjs inadvertently forward header-like strings from Dynamodb records into response headers, bypassing expected sanitization because developers assume database values are safe.

Consider a Feathersjs service that retrieves a user record from Dynamodb and issues a redirect using a returnUrl attribute stored in the item. If the returnUrl contains a newline (e.g., https://example.com\r\nSet-Cookie: token=evil), the server may split the response and inject additional headers. This maps to common OWASP API Top 10 API1:2023 — Broken Object Level Authorization when combined with BOLA, and it can facilitate session fixation or XSS via injected headers.

Real-world attack patterns include using newline characters (CRLF, %0d%0a) to inject headers such as X-Forwarded-For or Set-Cookie. If the Feathersjs app uses Dynamodb conditional writes or streams that echo user attributes into headers, the risk increases. For instance, an item attribute like custom_header used in res.set('x-custom', item.custom_header) without sanitization can lead to response splitting.

Because middleBrick scans the unauthenticated attack surface and tests input validation and HTTP response handling, it can identify Header Injection vectors that originate from Dynamodb-sourced data in Feathersjs endpoints. The scanner treats newline injection and unexpected header reflection as high-severity findings and provides remediation guidance focused on input validation and output encoding.

Dynamodb-Specific Remediation in Feathersjs — concrete code fixes

To remediate Header Injection in Feathersjs when using Dynamodb, ensure that any data derived from Dynamodb records is validated and sanitized before being used in headers. Below are concrete code examples that demonstrate secure patterns.

1. Avoid using user-controlled fields in headers

Instead of directly setting a header from a Dynamodb item attribute, either omit the header or use a server-controlled value. For example, do not do this:

// Insecure: using item attribute directly in a header
app.service('users').hooks({
  after: {
    find: async context => {
      if (context.result.data) {
        const item = context.result.data[0];
        // Risk: item.redirectUrl may contain newline characters
        context.result.redirect = `https://api.example.com${item.redirectUrl}`;
        // This may later be used to set headers, leading to injection
      }
      return context;
    }
  }
});

Secure alternative: validate and restrict the URL to a safe prefix, and avoid using it to set response headers that reflect user input.

// Secure: validate and use server-controlled logic
const validPrefixes = ['https://app.example.com/return', 'https://trusted.example.com/complete'];
app.service('users').hooks({
  after: {
    find: async context => {
      if (context.result.data) {
        for (const item of context.result.data) {
          const allowed = validPrefixes.some(prefix => item.returnUrl?.startsWith(prefix));
          if (!allowed) {
            item.returnUrl = '/fallback';
          }
        }
      }
      return context;
    }
  }
});

2. Sanitize any header-like fields before setting headers

If you must set headers derived from Dynamodb data, strip or encode newline characters and restrict allowed characters. For example, when setting a custom header:

// Secure: sanitize header values from Dynamodb items before use
const sanitizeHeaderValue = (value) => {
  if (typeof value !== 'string') return '';
  // Remove CR and LF to prevent response splitting
  return value.replace(/[\r\n]+/g, '');
};

app.service('reports').hooks({
  after: {
    get: async context => {
      const item = context.result;
      const safeValue = sanitizeHeaderValue(item.reportId || '');
      if (safeValue) {
        context.result.headers = {
          'X-Report-ID': safeValue
        };
      }
      return context;
    }
  }
});

3. Use framework-level validation for redirect URLs

When implementing redirects after a Dynamodb lookup, validate the target against a strict allowlist or a safe pattern (e.g., same-origin URLs). Do not rely on client-supplied URLs stored in Dynamodb.

// Secure: strict allowlist for redirect targets in Feathersjs hooks
const allowedHosts = new Set(['app.example.com', 'static.example.com']);
const url = require('url');

app.service('tokens').hooks({
  after: {
    create: async context => {
      const item = context.result;
      let target;
      try {
        target = new url.URL(item.redirect);
      } catch (err) {
        target = new url.URL('/dashboard', 'https://app.example.com');
      }
      if (!allowedHosts.has(target.hostname)) {
        target = new url.URL('/dashboard', 'https://app.example.com');
      }
      // Use a server-controlled Location header instead of item.redirect
      context.result.redirect = target.toString();
      return context;
    }
  }
});

These examples ensure that data from Dynamodb is never directly reflected into HTTP headers without rigorous validation, mitigating Header Injection risks while preserving functionality.

Frequently Asked Questions

How can I test if my Feathersjs + Dynamodb endpoint is vulnerable to Header Injection?
Use middleBrick to scan your endpoint; it tests input validation and header reflection by injecting newline sequences and monitoring for unintended header splits. Remediate by validating and sanitizing any Dynamodb-sourced data before it reaches response headers.
Does middleBrick fix Header Injection findings automatically?
No. middleBrick detects and reports findings with remediation guidance. You must apply code fixes in your Feathersjs service, such as sanitizing Dynamodb fields and avoiding user-controlled header values.