Dictionary Attack in Feathersjs
How Dictionary Attack Manifests in FeathersJS
In FeathersJS, dictionary attacks primarily target the /authentication endpoint, which handles JWT-based login via the feathers-authentication plugin. The attack exploits two common Feathers-specific misconfigurations: (1) absence of rate limiting on the unauthenticated login route, and (2) overly verbose error messages that enumerate valid usernames or reveal credential validation differences.
A typical vulnerable Feathers app exposes a POST /authentication endpoint that accepts { "strategy": "local", "email": "...", "password": "..." }. Without throttling, an attacker can script rapid-fire attempts using common passwords (e.g., from rockyou.txt). Feathers' default local strategy returns distinct errors: "Invalid login" for unknown emails vs. "Invalid password" for correct email/wrong password. This allows attackers to first harvest valid email addresses via enumeration, then focus password guesses.
The vulnerability is exacerbated if the app uses Feathers' feathers-hooks-common populate hook or custom before hooks that inadvertently leak user existence via timing differences or side-channel data in responses. For example, a custom before hook that fetches user details before password verification could cause a 200ms delay for existing emails vs. 5ms for non-existent ones, enabling timing-based enumeration.
FeathersJS-Specific Detection
Detecting dictionary attack vulnerabilities in FeathersJS requires examining both the authentication service configuration and runtime behavior. First, inspect the Feathers app's src/authentication.js (or equivalent) for rate limiting middleware. A missing app.use('/authentication', rateLimit({ windowMs: 15*60*1000, max: 5 })) indicates exposure. Second, test error message uniformity: send POST /authentication with valid email/invalid password and invalid email; identical HTTP status (401) and generic message ("Invalid credentials") suggest mitigation.
Dynamic scanning with middleBrick automates this detection. When you submit a Feathers app's base URL, middleBrick's Rate Limiting check probes the /authentication endpoint with rapid sequential login attempts (simulating a dictionary attack). It measures response codes and timing to determine if: (a) the endpoint returns 429 Too Many Requests after threshold, (b) error messages are consistent, and (c) no user enumeration occurs via response differences. The scanner also cross-references any OpenAPI spec to locate the auth endpoint definition (paths:/authentication/post). For example, a scan might report: "Rate limiting missing on authentication endpoint (max 20 attempts allowed)" with a severity of High.
Additionally, middleBrick's Input Validation check flags if the local strategy accepts trivial passwords (e.g., "password") by testing against a common password list, though this is more about credential strength than brute-force.
FeathersJS-Specific Remediation
Remediation in FeathersJS focuses on two layers: rate limiting at the Express middleware level and homogenizing authentication errors via hooks. First, install and apply express-rate-limit specifically to the /authentication path. In your Feathers app's main file (e.g., src/app.js):
const rateLimit = require('express-rate-limit');
const app = express();
// Apply only to authentication endpoint
app.use('/authentication', 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'
}));Second, override Feathers' default authentication error messages to prevent enumeration. Create a custom hook that runs after the local strategy but before the response is sent. In src/hooks/standardize-auth-error.js:
module.exports = async context => {
// Only run on authentication service failures
if (context.error && context.error.code === 401) {
context.error.message = 'Invalid email or password';
// Optionally, ensure no user data leaks in error
delete context.error.data;
}
return context;
};
// In your authentication service configuration
app.service('authentication').hooks({
after: {
create: [ 'standardizeAuthError' ]
}
});For comprehensive protection, combine this with Feathers' feathers-permissions to restrict authentication attempts to specific IP ranges if applicable, and enforce strong password policies during user registration using a before create hook on the users service that validates against zxcvbn or similar.
After deploying these changes, rescan with middleBrick to verify the Rate Limiting and Authentication checks now pass. The CLI tool can be integrated into your CI/CD pipeline: middlebrick scan https://your-feathers-api.com --check rate-limiting to ensure the fix is persistent.
Frequently Asked Questions
Why are FeathersJS apps particularly vulnerable to dictionary attacks on the /authentication endpoint?
/authentication endpoint for JWT login, but the default feathers-authentication plugin does not include rate limiting. Developers must manually add middleware like express-rate-limit. Additionally, Feathers' default error handling for the local strategy returns different messages for 'user not found' vs 'invalid password', enabling user enumeration—a key precursor to targeted dictionary attacks.How does middleBrick specifically detect dictionary attack vulnerabilities in a FeathersJS API?
POST /authentication requests with common credentials (simulating a dictionary attack). It monitors for HTTP 429 responses (rate limiting), analyzes error message consistency, and measures response timing for enumeration clues. The scanner also checks if the OpenAPI spec (if provided) defines rate limiting headers (e.g., X-RateLimit-*) on the auth endpoint. Findings are reported under the 'Rate Limiting' and 'Authentication' categories with severity ratings.