Token Leakage in Feathersjs
How Token Leakage Manifests in Feathersjs
Token leakage in Feathersjs applications typically occurs through improper handling of authentication tokens across multiple attack vectors. The most common pattern involves JWT tokens being exposed in URLs, browser history, or server logs due to Feathersjs's default behavior with query parameters.
When Feathersjs services receive authentication tokens via query parameters (common in REST API calls), these tokens appear in server logs, browser history, and can be captured by intermediate proxies. This is particularly problematic in Feathersjs because the framework's default REST adapter accepts tokens through multiple channels without strict enforcement of token transmission methods.
Another Feathersjs-specific manifestation occurs through event streaming endpoints. When using Feathersjs's real-time features with Socket.io or Primus, authentication tokens can be inadvertently exposed in connection URLs or handshake parameters. The framework's default configuration may pass these tokens through channels that log connection details, creating exposure points.
Middleware ordering in Feathersjs applications can also create token leakage scenarios. If authentication middleware runs after logging middleware, sensitive tokens in request headers or parameters get logged before they're properly handled. This ordering issue is unique to Feathersjs's hook-based architecture and can lead to tokens appearing in application logs or monitoring systems.
Cross-site request forgery (CSRF) vulnerabilities in Feathersjs applications can result in token leakage when malicious sites trick authenticated users into making requests. The framework's default CSRF protection may be insufficient if not properly configured, allowing tokens to be transmitted to third-party domains through crafted requests.
Feathersjs's service hooks can inadvertently expose tokens when developers use console.log or debug statements that output request objects containing authentication headers. This is especially common during development but can persist in production if proper code review practices aren't followed.
Feathersjs-Specific Detection
Detecting token leakage in Feathersjs requires examining both the application code and runtime behavior. Start by reviewing your Feathersjs configuration files for authentication settings that accept tokens through insecure channels.
// Check for insecure token handling in auth configuration
const authentication = {
local: {
entity: 'user',
service: 'users',
usernameField: 'email',
passwordField: 'password'
},
jwt: {
header: { typ: 'access' },
audience: 'https://yourdomain.com',
issuer: 'feathers',
algorithm: 'HS256'
}
};Scan your Feathersjs application for services that accept authentication parameters through query strings. Look for patterns where tokens appear in URLs or are passed through HTTP parameters rather than secure headers.
// Insecure pattern - tokens in query parameters
app.service('messages').find({
query: {
accessToken: 'eyJhbGciOiJIUzI1NiIs...'
}
Use middleBrick's CLI to scan your Feathersjs API endpoints for token leakage vulnerabilities. The scanner specifically checks for tokens in URLs, logs, and insecure transmission channels.
# Scan your Feathersjs API with middleBrick
npx middlebrick scan https://yourapi.com/messages
# Or integrate into your CI/CD pipeline
npx middlebrick scan --config middlebrick.jsonmiddleBrick's scanner identifies Feathersjs-specific issues like tokens in REST parameters, insecure JWT handling, and middleware ordering problems that could lead to token exposure. The tool provides detailed findings with severity levels and Feathersjs-specific remediation guidance.
Monitor your Feathersjs application logs for any appearance of authentication tokens. Set up log monitoring to alert when tokens appear in log files, which indicates leakage through the logging pipeline.
Feathersjs-Specific Remediation
Fixing token leakage in Feathersjs requires implementing secure token handling patterns and configuring the framework to reject insecure transmission methods. Start by enforcing strict token transmission policies in your authentication configuration.
// Secure authentication configuration
const authentication = {
jwt: {
header: { typ: 'access' },
audience: 'https://yourapi.com',
issuer: 'feathers',
algorithm: 'HS256',
extractors: [{
fromHeader: 'Authorization',
headerName: 'Bearer'
}]
}
};Implement middleware that sanitizes request objects before they reach logging or monitoring systems. Create a Feathersjs hook that removes sensitive information from request objects.
// Sanitize hook to prevent token leakage
const sanitizeHook = context => {
if (context.params.authenticated) {
};
// Apply before logging or monitoring hooks
app.service('messages').hooks({
before: {
Configure your Feathersjs services to reject authentication through query parameters and enforce header-only token transmission.
// Service configuration to prevent token leakage
app.service('messages').hooks({
before: {
{
Implement proper logging practices in your Feathersjs application by creating a custom logger that filters out sensitive authentication data.
// Custom logger that prevents token leakage
const safeLogger = (message, data) => {
const sensitiveKeys = ['password', 'token', 'accessToken', 'auth'];
{
console.log(message, safeData);
};Use middleBrick's continuous monitoring features to regularly scan your Feathersjs API for token leakage vulnerabilities. The Pro plan includes scheduled scans that can alert you when new token exposure risks are detected.
# Configure continuous monitoring with middleBrick
npx middlebrick monitor --api-url https://yourapi.com --schedule daily --alert slackImplement proper error handling in your Feathersjs application to prevent stack traces or error messages from exposing authentication tokens or sensitive user information.
// Secure error handling
app.configure(authentication);
app.set('query', {
whitelist: ['$select', '$limit', '$skip', '$sort']
// Custom error handler
app.error((error, context) => {
const safeError = {
};
console.error(safeError);
});