HIGH jwt misconfigurationfeathersjshmac signatures

Jwt Misconfiguration in Feathersjs with Hmac Signatures

Jwt Misconfiguration in Feathersjs with Hmac Signatures — how this specific combination creates or exposes the vulnerability

FeathersJS is a popular JavaScript framework for building APIs and real-time applications. When using JSON Web Tokens (JWT) for authentication, the choice of signing algorithm and configuration directly impacts security. Using HMAC signatures (e.g., HS256) introduces risks if the secret is weak, shared across services, or if the token validation logic is permissive.

One common misconfiguration is accepting tokens with the none algorithm. If a FeathersJS service does not explicitly enforce a signing algorithm, an attacker can craft a JWT with a alg: "none" header and a valid-looking payload. The server may then verify the token as unauthenticated, granting access without proper credentials. This bypasses HMAC-based protections entirely.

Another vulnerability arises from using a weak or compromised HMAC secret. HMAC relies on a shared secret; if this secret is short, predictable, or leaked, an attacker can forge tokens. In FeathersJS, if the secret is stored in environment variables that are accidentally exposed (for example, through debug endpoints or logs), the entire authentication scheme is compromised. Tokens signed with a known secret can be generated and used to escalate privileges or impersonate other users.

Additionally, insufficient token validation can lead to security issues. For instance, not validating the iss (issuer), aud (audience), or exp (expiration) claims allows tokens from other services or expired tokens to be accepted. In a FeathersJS application, if the JWT configuration does not explicitly set these validations, an attacker may reuse tokens across environments or prolong access beyond intended lifetimes.

FeathersJS applications that expose unauthenticated endpoints while also using HMAC-signed JWTs may inadvertently allow token enumeration or injection if input validation is weak. For example, if error messages differ based on whether a token is valid, an attacker can infer the presence of valid tokens. This can be chained with other weaknesses to conduct further attacks, such as privilege escalation via BOLA/IDOR if the token contains user identifiers that are not properly enforced.

Lastly, if the FeathersJS service does not enforce HTTPS, tokens signed with HMAC can be intercepted during transmission. Even with a strong secret, transmitting JWTs over unencrypted channels exposes them to session hijacking. The combination of weak transport security and permissive JWT validation amplifies the risk of token theft and misuse.

Hmac Signatures-Specific Remediation in Feathersjs — concrete code fixes

To secure FeathersJS applications using HMAC-signed JWTs, configuration must explicitly enforce algorithm restrictions, validate standard claims, and protect the shared secret. The following examples demonstrate secure practices.

1. Enforce HS256 and Reject the none Algorithm

Ensure the JWT verification settings specify the allowed algorithm and do not accept unsigned tokens.

const feathers = require('@feathersjs/feathers');
const authentication = require('@feathersjs/authentication');
const jwt = require('@feathersjs/authentication-jwt');

const app = feathers();

app.configure(authentication({
  secret: process.env.JWT_SECRET,
  entity: 'user',
  service: 'authentication',
  strategies: ['jwt'],
  jwt: {
    // Explicitly set the algorithm to HS256
    algorithms: ['HS256'],
    // Do not allow 'none' or other algorithms
    allowInsecureToken: false
  }
}));

app.use('/authentication', authentication());

2. Validate Standard Claims

Configure JWT validation to check issuer, audience, and expiration to prevent token misuse across services.

app.configure(authentication({
  secret: process.env.JWT_SECRET,
  entity: 'user',
  service: 'users',
  strategies: ['jwt'],
  jwt: {
    algorithms: ['HS256'],
    // Validate standard claims
    issuer: 'my-feathers-app',
    audience: 'my-feathers-client',
    expiresIn: '1h'
  }
}));

3. Secure the HMAC Secret

Store the secret in environment variables and ensure it is sufficiently long and random. Avoid hardcoding secrets in source code.

// .env file
JWT_SECRET=super-strong-random-secret-32-bytes-long-abc123xyz

// In your FeathersJS configuration
const jwtSecret = process.env.JWT_SECRET;
if (!jwtSecret || jwtSecret.length < 32) {
  throw new Error('JWT_SECRET must be a strong, 32+ character value');
}

4. Use Middleware for Additional Validation

Add custom hooks to verify token usage context, such as checking against a revocation list or binding tokens to IP ranges.

app.service('authentication').hooks({
  before: {
    create: [context => {
      const { token } = context.data;
      if (!token) {
        throw new Error('Token is required');
      }
      // Additional custom validation logic can be added here
      return context;
    }]
  }
});

5. Enforce HTTPS in Production

Ensure that all API communications occur over HTTPS to prevent token interception, especially when using HMAC-based tokens.

// In production configuration
app.set('host', 'https://api.myapp.com');

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

What is the risk of using the 'none' algorithm in JWTs with FeathersJS?
Using the 'none' algorithm allows an attacker to forge tokens without knowing the secret. FeathersJS must explicitly enforce algorithm restrictions to prevent this bypass.
How can HMAC secret leakage impact my FeathersJS application?
If the HMAC secret is exposed, an attacker can sign arbitrary tokens and impersonate users. Protect the secret using environment variables and strong, random values.