HIGH log injectionfeathersjsbasic auth

Log Injection in Feathersjs with Basic Auth

Log Injection in Feathersjs with Basic Auth — how this specific combination creates or exposes the vulnerability

Log injection occurs when untrusted data is written directly into log files without proper sanitization, enabling an attacker to forge log entries or inject malicious content such as newlines or structured text. In Feathersjs applications that use HTTP Basic Authentication, this risk is realized through two converging dimensions: the way Basic Auth credentials are handled and how Feathers services log events.

Feathersjs is a framework for building REST and real-time APIs. When Basic Auth is implemented naively, the service may log user-supplied or derived values—such as the username from the Authorization header—without validation or escaping. If an attacker sends crafted credentials containing newline characters (e.g., admin%0aMalicious:password), the injected newline can split the log line and append arbitrary text, corrupting log structure and potentially hiding evidence of abuse or enabling log forging.

Consider a typical Feathers authentication hook where the username is extracted and recorded:

// src/hooks/log-auth.js
module.exports = function () {
  return async context => {
    const { username } = context.params;
    console.log(`User authenticated: ${username}`);
    return context;
  };
};

If the username originates from a Basic Auth header and is not sanitized, an attacker can supply user%0aAuthorization:%20Basic%20.... The injected newline causes the log entry to be followed by an additional line that may appear as a valid Authorization header, misleading operators during incident review. This is a classic log injection vector that leverages uncontrolled input directly into structured log output.

Moreover, because Feathers services often emit logs during authentication and authorization events, the combination with Basic Auth increases the likelihood that injected content is privileged or administrative in nature. If logs are aggregated into monitoring or SIEM tools, forged entries can bypass detection rules that assume log integrity. This does not imply the framework is inherently insecure, but it highlights how implementation choices—such as logging raw user identity fields—can expose log injection risks when paired with Basic Auth flows.

Remediation focuses on sanitizing data before it reaches the logging layer and ensuring that authentication hooks treat credentials as untrusted input. The framework itself does not introduce the flaw; rather, it is the developer’s responsibility to validate and escape any data destined for logs.

Basic Auth-Specific Remediation in Feathersjs — concrete code fixes

Securing Feathersjs services that use Basic Auth against log injection requires disciplined input handling and safe logging practices. The following patterns illustrate concrete fixes that prevent injection while preserving functionality.

1. Sanitize usernames before logging

Strip or escape newline characters and control characters from any user-controlled value before writing to logs. A simple approach is to replace line breaks with a safe placeholder or remove them entirely.

// src/hooks/safe-log-auth.js
function escapeNewline(value) {
  return typeof value === 'string'
    ? value.replace(/[\r\n\u2028\u2029]/g, ' ')
    : value;
}

module.exports = function () {
  return async context => {
    const { username } = context.params;
    const safeUsername = escapeNewline(username);
    console.log(`User authenticated: ${safeUsername}`);
    return context;
  };
};

This ensures that injected newlines cannot break the log line structure or append additional content.

2. Use structured logging with explicit field separation

Instead of concatenating values into a single string, emit structured logs (e.g., JSON) so that each field is parsed independently by log collectors. This prevents newline injection from altering the semantic boundaries of log entries.

// src/hooks/structured-auth.js
module.exports = function () {
  return async context => {
    const { username } = context.params;
    const logEntry = {
      event: 'user_authenticated',
      username: username,
      timestamp: new Date().toISOString()
    };
    console.log(JSON.stringify(logEntry));
    return context;
  };
};

With JSON logging, a newline in the username is treated as a character within a string field and does not affect log parsing.

3. Validate and restrict Basic Auth credentials at the hook level

Apply validation rules to the username and password early in the request lifecycle. For example, reject usernames containing control characters or patterns that could be used for injection.

// src/hooks/validate-basic-auth.js
module.exports function validateBasicAuth() {
  return async context => {
    const auth = context.params.headers && context.params.headers.authorization;
    if (auth && auth.startsWith('Basic ')) {
      const decoded = Buffer.from(auth.slice(6), 'base64').toString('utf8');
      const [username, password] = decoded.split(':');
      if (!username || /[\r\n]/.test(username) || /[\r\n]/.test(password)) {
        throw new Error('Invalid credentials');
      }
      // Attach cleaned values for downstream use
      context.params.user = { username, password };
    }
    return context;
  };
}

Plug this hook into your Feathers service pipeline before authentication logic to enforce safe input.

These steps ensure that log injection risks are mitigated without altering the Basic Auth mechanism itself. By treating all user data as potentially malicious and structuring logs appropriately, developers can maintain both security and observability.

Frequently Asked Questions

Why is newline injection particularly dangerous in authentication logs?
Newline injection can forge additional log lines, allowing attackers to obfuscate malicious activity or impersonate privileged operations within authentication records.
Does using JSON logging fully eliminate log injection risks?
JSON logging prevents line-based injection from breaking structure, but developers must still validate input to avoid logical injection issues and ensure proper escaping of special characters within string fields.