Token Leakage in Feathersjs with Hmac Signatures
Token Leakage in Feathersjs with Hmac Signatures — how this specific combination creates or exposes the vulnerability
FeathersJS is a framework for real-time web applications that commonly uses JWTs for authentication. When Hmac Signatures are used to sign tokens, token leakage can still occur through multiple channels despite the cryptographic integrity of the signature. Token leakage refers to the unintended exposure of authentication tokens, which can lead to account takeover or privilege escalation.
One common scenario in FeathersJS applications is logging or debugging output that inadvertently includes the full token. For example, if an error handler prints the token to the console or includes it in error responses, attackers with log access can harvest valid tokens. Another vector is client-side storage: storing the Hmac-signed token in local storage or insecure cookies makes it susceptible to cross-site scripting (XSS) theft. Even with a strong Hmac signature, once the token is leaked, an attacker can replay it until expiration.
Additionally, misconfigured CORS or missing secure flags on cookies can expose tokens in transit or allow cross-origin leakage. FeathersJS services that rely on Hmac Signatures must ensure tokens are transmitted over HTTPS and are not embedded in URLs or query parameters, which can be logged in server access logs or browser history. The signature itself does not prevent leakage; it only ensures that a stolen token has not been tampered with. Therefore, protecting the token at every layer — storage, transmission, and handling — is essential.
Real-world patterns include services using the @feathersjs/authentication-jwt hook where the token is attached to the response object without proper sanitization. If the response is logged in full (e.g., via middleware or client-side debugging), the token is exposed. Another pattern is the use of non-HTTPS endpoints during development, which allows token interception on the network path.
Consider the OWASP API Top 10 risk Broken Object Level Authorization (BOLA); leaked tokens can directly enable BOLA attacks when an attacker uses a valid token to access another user’s resources. While Hmac Signatures protect integrity, they do not mitigate exposure. Proper remediation requires strict control over where and how tokens are stored, transmitted, and logged.
Hmac Signatures-Specific Remediation in Feathersjs — concrete code fixes
To mitigate token leakage when using Hmac Signatures in FeathersJS, focus on secure token handling, transport, and logging hygiene. Below are concrete code examples and configuration steps.
1. Secure Token Transmission with HTTPS and Secure Cookies
Ensure tokens are only sent over HTTPS and stored in cookies with the Secure and HttpOnly flags. Here is a FeathersJS hook that enforces secure transport:
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
const app = express(feathers());
app.configure(express.rest());
app.configure(express.socketio());
// Middleware to enforce HTTPS in production
app.use((req, res, next) => {
if (process.env.NODE_ENV === 'production' && !req.secure) {
return res.status(403).send('HTTPS required');
}
next();
});
// Configure authentication with secure cookies
const authentication = require('@feathersjs/authentication');
const jwt = require('@feathersjs/authentication-jwt');
app.configure(authentication({
secret: process.env.AUTH_SECRET,
strategies: ['jwt'],
cookieOptions: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict'
}
}));
app.use('/authentication', authentication());
app.use('/authentication', jwt());
2. Avoid Logging Tokens in Error Handling
Ensure that error handlers do not include tokens in logs or responses. Customize the error formatter in FeathersJS:
app.set('errors', {
formatter: (error, stack, options) => {
// Remove token from error before logging
const safeError = { ...error };
if (safeError.accessToken) {
safeError.accessToken = '[REDACTED]';
}
if (safeError.refreshToken) {
safeError.refreshToken = '[REDACTED]';
}
if (process.env.NODE_ENV !== 'test') {
console.error(safeError);
}
return safeError;
}
});
3. Validate Token Storage on the Client
When using Hmac Signatures, instruct clients to store tokens in memory or in secure, same-site cookies rather than local storage. Example client-side initialization with secure settings:
import { AuthenticationService } from '@feathersjs/authentication-client';
import { JwtService } from '@feathersjs/authentication-client';
const authService = new AuthenticationService('/authentication', {
storage: {
getItem: (key) => sessionStorage.getItem(key),
setItem: (key, value) => sessionStorage.setItem(key, value),
removeItem: (key) => sessionStorage.removeItem(key)
}
});
const jwt = new JwtService(authService);
4. Middleware to Strip Tokens from Logs
Add an Express middleware to scrub tokens from request logs:
app.use((req, res, next) => {
if (req.headers.authorization) {
req.headers.authorization = 'Bearer [REDACTED]';
}
next();
});
These steps ensure that Hmac-signed tokens remain protected against leakage while preserving the integrity checks provided by the signature mechanism.