Log Injection in Feathersjs
How Log Injection Manifests in Feathersjs
Log injection in Feathersjs occurs when untrusted data provided by a client is written directly into application or framework logs without sanitization. Feathersjs services often log request metadata such as params, query strings, and payload contents via transport hooks. If a developer writes custom logs inside a service hook using unchecked user input, an attacker can inject newline sequences or structured tokens that corrupt log semantics.
Attack patterns specific to Feathersjs include injecting newline characters (\n) or carriage returns to separate malicious log entries, or embedding structured markers that mimic Feathersjs log formats. For example, an attacker may provide a name field containing \n[Malicious] injected: true in a before hook, causing the log to appear as an internal diagnostic event. Another pattern is injecting JSON-like fragments into log lines if the transport (e.g., transports.logger or a custom transport) uses a formatter that assumes trusted input.
Feathersjs-specific code paths that are prone to log injection include hook implementations that call service.logger or external logger instances with user-controlled strings. Consider a hook that logs the id from params without validation:
const { Service } = require('@feathersjs/feathers');
const app = new Service();
app.hooks({
before: {
create: [context => {
const { data, params } = context;
// Risk: directly using user-controlled values in logs
context.app.log.info(`Creating resource with data: ${JSON.stringify(data)} for user: ${params.user && params.user.name}`);
return context;
}]
}
});
If data or params.user.name contains newline or structured injection payloads, the log file can be polluted with misleading entries. Similarly, using transports such as @feathersjs/transport-commons with custom log formats that concatenate user fields into a message string exposes the same risk. Attackers may leverage log injection to bypass log-based monitoring, obscure real events, or set up conditions for log forging that affect auditability.
Feathersjs-Specific Detection
Detecting log injection in Feathersjs requires analyzing hooks and transports where user input reaches log statements. middleBrick scans the unauthenticated attack surface and checks runtime behavior for indicators of unsafe logging patterns. While scanning, it does not rely on internal architecture but focuses on observable outputs and configuration that suggest missing input validation.
To identify issues manually, review hook files for direct string interpolation that includes fields like params.query, data, or any value derived from the request. Search for patterns such as .log.info, .log.warn, or transport emits that include concatenated strings with user data. Ensure log lines are either static or use structured formats that escape newlines and special characters. middleBrick’s checks include Input Validation and Unsafe Consumption categories, which surface endpoints where attacker-controlled data may reach logging paths.
Example of a safe logging pattern in Feathersjs that mitigates log injection by sanitizing newlines and structured tokens:
const escapeLogString = (str) => {
if (typeof str !== 'string') return str;
return str.replace(/[\r\n]+/g, ' ').replace(/\[/g, '{LSB}').replace(/\]/g, '{RSB}');
};
app.hooks({
before: {
update: [context => {
const { data, params } = context;
const safeName = escapeLogString((params.user && params.user.name) || 'unknown');
context.app.log.info(`Updating resource id=${context.id} data=${JSON.stringify(data)} user=[${safeName}]`);
return context;
}]
}
});
Using middleBrick’s GitHub Action or CLI can integrate this detection into CI/CD, flagging endpoints where logs may be influenced by untrusted data. The dashboard helps track findings over time and prioritize remediation based on severity and category breakdowns.
Feathersjs-Specific Remediation
Remediation in Feathersjs focuses on ensuring that any data written to logs is sanitized and that structured logging does not trust raw user input. Use a consistent sanitization function that removes or escapes control characters and tokens that could be misinterpreted by log parsers.
Prefer structured logging libraries that safely serialize objects rather than concatenating strings. If you must use string interpolation, escape newlines, carriage returns, and bracket-like tokens that could mimic internal markers. Below is an example using a sanitization helper and a safe log call within a Feathersjs hook:
const sanitizeForLog = (value) => {
if (value == null) return String(value);
const str = typeof value === 'string' ? value : JSON.stringify(value);
return str.replace(/[\r\n]+/g, ' ').replace(/\//g, '/').replace(/\\/g, '\\\\');
};
app.hooks({
before: {
patch: [context => {
const { id, data } = context;
const safeData = sanitizeForLog(data);
const provider = sanitizeForLog(context.params.provider || 'unknown');
context.app.log.debug(`patch id=${id} data=${safeData} provider=${provider}`);
return context;
}]
}
});
Additionally, configure transports to avoid formats that encourage concatenation. If using a custom transport, ensure it treats message templates as immutable and passes structured metadata separately rather than embedding it in the message string. Regular audits via middleBrick scans help verify that new hooks or services do not reintroduce log injection risks.