HIGH broken authenticationfeathersjs

Broken Authentication in Feathersjs

How Broken Authentication Manifests in Feathersjs

Broken authentication in Feathersjs often stems from misconfigured authentication hooks, improper session management, or inadequate validation of user credentials. Feathersjs uses a pluggable authentication system where services can be protected with authenticate hooks, but developers frequently make critical mistakes in implementation.

One common vulnerability occurs when developers forget to apply authentication hooks to critical services. For example, an admin management service might be exposed without proper authentication:

const adminService = app.service('admin/users');
// Missing authentication hook!
// Any unauthenticated user can access this service

Another frequent issue involves improper JWT validation. Feathersjs supports multiple JWT strategies, but developers sometimes use weak secret keys or fail to validate token expiration:

// INSECURE: Hardcoded weak secret
const authService = new AuthenticationService(app, {
  secret: 'password123', // Easily guessable
  strategies: ['jwt']
});

Session fixation attacks are particularly problematic in Feathersjs applications that use session-based authentication. If session IDs aren't properly regenerated after login, attackers can fixate sessions and hijack accounts:

// INSECURE: Session ID not regenerated
app.post('/login', async (req, res) => {
  const user = await findUser(req.body);
  if (user) {
    req.session.user = user; // Session fixation vulnerability
    res.json({ success: true });
  }
});

Feathersjs's flexible authentication system can also lead to privilege escalation when role-based access control (RBAC) isn't properly enforced. Developers might check user roles in service methods but forget to protect the entire service:

class AdminService {
  async find(params) {
    // INSECURE: Role check only in method
    if (!params.user.roles.includes('admin')) {
      throw new Forbidden('Admin access required');
    }
    return this._super.find(params);
  }
}
// But the service itself isn't protected by an authentication hook

Credential stuffing becomes easier when Feathersjs applications don't implement proper rate limiting on authentication endpoints. Without rate limiting, attackers can brute-force passwords indefinitely:

// INSECURE: No rate limiting on login
app.post('/login', async (req, res) => {
  const { email, password } = req.body;
  const user = await User.authenticate('local', { email, password });
  // No rate limiting, no account lockout
  res.json(user);
});

Feathersjs-Specific Detection

Detecting broken authentication in Feathersjs requires both static code analysis and dynamic runtime testing. Start by examining your authentication configuration and service protection patterns.

Static analysis should focus on these key areas:

// Check for missing authentication hooks
const unprotectedServices = [
  'admin/*',
  'settings/*',
  'users/me'
].filter(path => {
  const service = app.service(path);
  return !service.hooks || !service.hooks._before.some(h => h.name === 'authenticate');
});

Verify your JWT configuration for security best practices:

const jwtConfig = app.get('authentication');
const issues = [];
if (jwtConfig.secret.length < 32) {
  issues.push('JWT secret too short');
}
if (jwtConfig.expiresIn && jwtConfig.expiresIn < '1h') {
  issues.push('JWT expiration too short');
}
if (!jwtConfig.issuer || !jwtConfig.audience) {
  issues.push('JWT issuer/audience not configured');
}

Dynamic testing with middleBrick can identify authentication bypasses that static analysis misses. middleBrick's black-box scanning tests unauthenticated access to protected endpoints:

npm install -g middlebrick
middlebrick scan https://api.yourapp.com/users/me \
  --report=json > auth-report.json

# middleBrick will test:
# - Access to protected endpoints without authentication
# - JWT token validation weaknesses
# - Session management vulnerabilities
# - Rate limiting effectiveness

middleBrick's LLM/AI Security module is particularly valuable for Feathersjs applications using AI features, as it tests for system prompt leakage and prompt injection vulnerabilities that could bypass authentication logic in AI-powered services.

Manual penetration testing should include:

  • Testing for default credential acceptance
  • Verifying account lockout mechanisms
  • Checking for session fixation vulnerabilities
  • Testing privilege escalation paths
  • Verifying JWT token tampering resistance

Feathersjs-Specific Remediation

Securing authentication in Feathersjs requires a defense-in-depth approach using the framework's built-in features and security best practices.

Start with proper authentication hook configuration. Apply authentication globally to protected services:

const { authenticate } = require('@feathersjs/authentication').hooks;

// Secure all admin services
app.service('admin').hooks({
  before: {
    all: [
      authenticate('jwt'), // Require JWT for all admin operations
      query.withParams(), // Prevent parameter injection
    ]
  }
});

Implement strong JWT configuration with proper secrets and validation:

const crypto = require('crypto');

const authService = new AuthenticationService(app, {
  secret: crypto.randomBytes(32).toString('base64'), // 256-bit random secret
  strategies: ['jwt'],
  jwt: {
    header: { alg: 'HS256' },
    expiresIn: '24h',
    issuer: 'your-app.com',
    audience: 'your-app.com'
  }
});

Prevent session fixation by regenerating session IDs after authentication:

app.post('/login', async (req, res) => {
  const { email, password } = req.body;
  
  try {
    const user = await User.authenticate('local', { email, password });
    
    // Regenerate session to prevent fixation
    req.session.regenerate(err => {
      if (err) return res.status(500).json({ error: 'Session error' });
      
      req.session.user = user;
      res.json({ success: true, user });
    });
  } catch (error) {
    res.status(401).json({ error: 'Invalid credentials' });
  }
});

Implement rate limiting on authentication endpoints using Feathersjs middleware:

const rateLimit = require('express-rate-limit');

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 5, // Limit each IP to 5 requests per windowMs
  message: 'Too many login attempts, please try again later',
  standardHeaders: true,
  legacyHeaders: false,
});

app.post('/login', loginLimiter, async (req, res) => {
  // Authentication logic here
});

Secure role-based access control using Feathersjs's authorization hooks:

const { iff, isProvider, fastJoin } } from 'feathers-hooks-common';

const adminOnly = context => context.params.user.roles.includes('admin');

app.service('admin/users').hooks({
  before: {
    all: [
      authenticate('jwt'),
      iff(adminOnly, fastJoin(protectAdminData)) // Only admins see sensitive data
    ]
  }
});

const protectAdminData = mergeSchema({
  admin: () => false
});

Enable continuous monitoring with middleBrick's Pro plan to automatically scan your Feathersjs APIs for authentication vulnerabilities:

# Add to GitHub Actions for CI/CD security
- name: Scan API Security
  uses: middlebrick/middlebrick-action@v1
  with:
    url: ${{ secrets.API_URL }}
    fail-on-severity: high
    token: ${{ secrets.MIDDLEBRICK_TOKEN }}

Related CWEs: authentication

CWE IDNameSeverity
CWE-287Improper Authentication CRITICAL
CWE-306Missing Authentication for Critical Function CRITICAL
CWE-307Brute Force HIGH
CWE-308Single-Factor Authentication MEDIUM
CWE-309Use of Password System for Primary Authentication MEDIUM
CWE-347Improper Verification of Cryptographic Signature HIGH
CWE-384Session Fixation HIGH
CWE-521Weak Password Requirements MEDIUM
CWE-613Insufficient Session Expiration MEDIUM
CWE-640Weak Password Recovery HIGH

Frequently Asked Questions

How can I test if my Feathersjs authentication is properly configured?
Use middleBrick's black-box scanning to test unauthenticated access to protected endpoints. The scanner will attempt to access admin services, user data, and other protected resources without credentials to identify authentication bypasses. You can also manually test by attempting to access protected routes without JWT tokens or with expired tokens to verify proper access control.
What's the best way to handle JWT token refresh in Feathersjs applications?
Implement a refresh token mechanism where short-lived access tokens (15-30 minutes) are paired with long-lived refresh tokens stored in HTTP-only cookies. Use Feathersjs's authentication service to handle token rotation and implement proper validation of refresh tokens. Always validate the original access token's claims and ensure refresh tokens are properly scoped and revocable.