Log Injection in Feathersjs with Api Keys
Log Injection in Feathersjs with Api Keys — how this specific combination creates or exposes the vulnerability
Log injection occurs when untrusted input is written directly into log entries without sanitization, enabling attackers to forge log lines, obscure true events, or inject malicious content such as newlines or structured message fragments. In FeathersJS applications that rely on API keys for authentication, combining key validation logic with insecure logging practices can amplify risks.
When an API key is accepted via headers or query parameters and then echoed into logs without validation, an attacker can supply a key containing carriage returns or other control characters. Because many log formats are line-based (e.g., JSON Lines or newline-delimited text), a newline in the key can terminate the current log entry and start a new one. This can corrupt audit trails and enable log forging, where an attacker makes it appear that a privileged operation or a different key was used.
Consider a FeathersJS service that authenticates requests by checking an api_key header and logs the key for debugging. If the key abc\nDELETE /users is accepted, the log may show two separate entries: one for the legitimate key and another seemingly legitimate command. Because the scan checks Input Validation and the logging implementation as part of its 12 checks, it flags log injection surfaces where keys are reflected without sanitization. The same risk applies when keys are included in URLs or as form fields; reflected keys in logs can disclose sensitive patterns or aid in social engineering.
In a broader security context, log injection intersects with requirements around traceability and integrity. Attackers may exploit injected newlines to bypass simple log-based monitoring rules or to hide follow-up actions. Because FeathersJS services often integrate with external authentication providers, improperly handled keys can also complicate forensic analysis. The scanner’s Input Validation and Data Exposure checks highlight these risks by correlating how keys are accepted, processed, and recorded, emphasizing the need to treat API keys as untrusted input.
Api Keys-Specific Remediation in Feathersjs — concrete code fixes
Remediation focuses on preventing untrusted API key content from corrupting logs. Do not log raw keys; instead, log stable, non-echoing references such as key identifiers or hashes. If keys must be recorded for debugging, sanitize newlines and control characters, and enforce strict validation rules.
Example: a FeathersJS service that authenticates using an API key header, logs only a key fingerprint, and validates key format.
const crypto = require('node:crypto');
const { Forbidden } = require('@feathersjs/errors');
// Assume app is a FeathersJS application with a `services/api-keys` service
app.hooks({
before: {
all: [context => {
const providedKey = context.params.headers['x-api-key'];
if (!providedKey || typeof providedKey !== 'string') {
throw new Forbidden('API key missing');
}
// Validate key format: alphanumeric, dashes, underscores, length constraints
if (!/^[A-Za-z0-9_-]{16,64}$/.test(providedKey)) {
throw new Forbidden('Invalid API key format');
}
// Authenticate by lookup (pseudo implementation)
const isValid = await context.app.service('api-keys').find({
query: { hash: hashKey(providedKey), $select: ['id', 'scope'] }
}).then(result => result.data.length > 0);
if (!isValid) {
// Log only a fingerprint, never the raw key
const fingerprint = crypto.createHash('sha256').update(providedKey).digest('hex').slice(0, 16);
context.params.logMeta = { keyFingerprint: fingerprint, scope: 'authenticated' };
return context;
}
throw new Forbidden('Invalid API key');
}]
}
});
function hashKey(key) {
return crypto.createHash('sha256').update(key).digest('hex');
}
Additional practices:
- Configure your logging framework (e.g., winston, pino) to redact fields named
apiKeyor similar before output. This prevents accidental inclusion even if a developer logs the full request object. - Normalize keys before any reflection: replace newlines, tabs, and carriage returns with safe placeholders or reject keys that contain them.
- Use structured logging with explicit fields rather than free-form messages; this makes it easier to filter and monitor without relying on regex on raw log lines.
- Correlate scans findings with your logging implementation. The scanner’s checks for Input Validation and Data Exposure can highlight whether keys appear in URLs, error messages, or logs, guiding focused fixes.