Format String in Feathersjs with Jwt Tokens
Format String in Feathersjs with Jwt Tokens — how this specific combination creates or exposes the vulnerability
A format string vulnerability occurs when user-controlled input is passed directly to a function that interprets format specifiers (e.g., %s, %d, %n) without proper sanitization. In FeathersJS, this typically arises when logging, error reporting, or string construction uses user-supplied data in functions like util.format or similar pattern-based substitutions. When JWT tokens are involved, developers sometimes embed token payloads or headers into log messages or error responses using format strings, inadvertently exposing the token or allowing an attacker to manipulate the output through injected format specifiers.
Consider a FeathersJS service that logs authentication events by directly interpolating token claims into a format string:
const util = require('util');
app.service('auth').hooks({
after: {
create: [context => {
const { token } = context.result;
const decoded = context.params.user;
console.log(util.format('User authenticated: %s, token: %s', decoded.sub, token));
return context;
}]
}
});
If an attacker can control decoded.sub (e.g., via a manipulated JWT with a modified payload), they may inject format specifiers such as %n to write to memory or %x to leak stack contents. While JWT tokens themselves are base64-encoded and not directly parsed by util.format, the surrounding application logic that combines user-influenced data with format strings creates a pathway for unintended behavior. In a broader security context, format string issues can lead to information disclosure or instability, which may complement other attack vectors such as Broken Access Control or insecure deserialization when tokens are mishandled.
Additionally, if error messages in FeathersJS are constructed using format-style concatenation with JWT-related data (e.g., token expiration details), an attacker could supply malformed input to trigger verbose errors that expose internal state. The framework does not inherently protect against format string misuse; it relies on developers to avoid passing untrusted data into formatting functions. This becomes especially relevant when using logging libraries or custom wrappers that accept format strings and multiple arguments, as the combination of JWT metadata and unchecked format directives increases the attack surface.
To align with best practices, always validate and sanitize inputs that interact with formatting routines, and avoid embedding sensitive token data directly in log output. Security checks such as those performed by middleBrick include validation for unsafe string operations and exposure of sensitive data, which can help identify risky patterns involving JWT tokens and format strings in your API surface.
Jwt Tokens-Specific Remediation in Feathersjs — concrete code fixes
Remediation focuses on eliminating direct use of user-controlled data in format strings and ensuring JWT handling follows secure patterns. Replace util.format with explicit string concatenation or templating that does not interpret format specifiers. For logging, use structured logging libraries or simple concatenation with sanitized values.
// Unsafe
const util = require('util');
app.service('auth').hooks({
after: {
create: [context => {
const { token } = context.result;
const decoded = context.params.user;
console.log(util.format('User authenticated: %s, token: %s', decoded.sub, token));
return context;
}]
}
});
// Secure: use explicit concatenation and avoid format specifiers
app.service('auth').hooks({
after: {
create: [context => {
const { token } = context.result;
const decoded = context.params.user;
console.log('User authenticated: ' + decoded.sub + ', token: ' + token);
return context;
}]
}
});
When working with JWTs in FeathersJS, ensure that token validation and decoding are performed using trusted libraries like jsonwebtoken, and never construct log messages or error responses using raw token payloads. Apply input validation to reject tokens with unexpected claims or malformed structures.
const jwt = require('jsonwebtoken');
app.service('auth').hooks({
before: {
create: [context => {
const { accessToken } = context.data;
try {
const decoded = jwt.verify(accessToken, process.env.JWT_SECRET);
context.params.user = decoded;
} catch (err) {
throw new Error('Invalid token');
}
return context;
}]
}
});
For production environments, consider using the middleBrick CLI to scan your FeathersJS endpoints and detect insecure logging or format string patterns as part of your security posture. The CLI can be integrated into scripts and pipelines to automate detection of such issues.
# Example CLI usage
middlebrick scan https://api.example.com
Additionally, the GitHub Action can enforce security thresholds in CI/CD, failing builds if risky patterns are identified in API definitions or runtime behavior. This helps prevent regressions where format string vulnerabilities might reappear alongside JWT handling logic.