Brute Force Attack with Bearer Tokens
How Brute Force Attack Manifests in Bearer Tokens
Brute force attacks on Bearer Tokens exploit the stateless nature of token-based authentication. Unlike session-based systems where failed attempts can be tracked server-side, Bearer Tokens present unique challenges for rate limiting and attack detection.
The most common attack pattern involves an attacker systematically trying different token values to gain unauthorized access. Since Bearer Tokens are often sent in HTTP headers, an attacker can send thousands of requests per minute from distributed sources without triggering traditional rate limiting mechanisms.
Consider this vulnerable implementation:
app.post('/api/protected', (req, res) => {
const token = req.headers.authorization?.replace('Bearer ', '');
// No rate limiting on token validation
if (!validateToken(token)) {
return res.status(401).json({ error: 'Invalid token' });
}
res.json({ data: 'protected resource' });
});
The vulnerability here is that token validation occurs without any throttling mechanism. An attacker can send millions of token variations until they find a valid one. This becomes particularly dangerous when tokens follow predictable patterns or when weak token generation algorithms are used.
Another manifestation occurs in API endpoints that accept tokens but don't properly validate them before processing requests. An attacker might send a valid token with malicious payloads, hoping to exploit business logic vulnerabilities once authenticated.
Multi-step authentication flows also present risks. If a system uses refresh tokens alongside access tokens, an attacker might brute force refresh tokens while the access token remains valid, eventually gaining persistent access.
The distributed nature of modern APIs amplifies this risk. Microservices architectures often have multiple endpoints accepting the same token type, creating numerous attack surfaces. An attacker can distribute their brute force attempts across different services, making detection even more difficult.
Bearer Tokens-Specific Detection
Detecting brute force attacks on Bearer Tokens requires specialized monitoring that goes beyond standard rate limiting. Traditional IP-based rate limiting fails because attackers use distributed networks and because legitimate users share networks.
Effective detection focuses on token-specific patterns. Monitor for repeated failed token validations from different sources. Look for tokens that appear across multiple failed authentication attempts - this indicates an attacker testing stolen tokens.
middleBrick's black-box scanning approach is particularly effective for detecting Bearer Token vulnerabilities. The scanner tests unauthenticated endpoints by sending various token patterns and analyzing responses. Here's how middleBrick detects brute force vulnerabilities:
// Example of middleBrick detection logic
const detectBruteForceVulnerability = async (url) => {
const testTokens = [
'invalid.token.here',
'Bearer invalid-token',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', // Malformed JWT
'AAAAAAAAAAAAAAAA', // Random string
];
const results = await Promise.all(testTokens.map(async (token) => {
const response = await fetch(url, {
headers: { 'Authorization': `Bearer ${token}` }
});
return {
token: token,
status: response.status,
time: Date.now()
};
}));
// Analyze patterns: consistent 401s with low response times may indicate lack of rate limiting
const isVulnerable = results.every(r => r.status === 401 && r.time < 100);
return isVulnerable ? 'High Risk' : 'Secure';
};
Key detection indicators include:
- Endpoints that respond to any Bearer token format without validation
- Consistent response times regardless of token validity
- Missing or ineffective rate limiting on authentication endpoints
- Endpoints that reveal whether a token exists without validating it
- API documentation that shows token generation patterns
middleBrick's scanner also checks for API endpoints that might leak information about token validity through response timing or error messages, which can aid brute force attacks.
Bearer Tokens-Specific Remediation
Securing Bearer Tokens against brute force attacks requires implementing multiple defensive layers. The most effective approach combines rate limiting, token complexity, and intelligent validation mechanisms.
Implement per-token rate limiting rather than just IP-based limiting:
// Node.js example with Redis-based rate limiting
const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
// Rate limit based on token hash, not IP
const tokenRateLimiter = rateLimit({
store: new RedisStore({
prefix: 'token_rl:',
expiry: 60 * 60 // 1 hour
}),
keyGenerator: (req) => {
const token = req.headers.authorization?.replace('Bearer ', '');
return token ? `token:${hash(token)}` : 'no-token';
},
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // limit each token to 5 requests per windowMs
message: 'Too many requests from this token'
});
app.use('/api/protected', tokenRateLimiter, (req, res) => {
// Protected endpoint logic
});
Enhance token validation with exponential backoff:
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
// Store token hashes in database with attempt tracking
async function validateToken(token) {
if (!token) return false;
const tokenHash = await bcrypt.hash(token, 12);
const storedToken = await db.tokens.findOne({ hash: tokenHash });
if (!storedToken) {
// Invalid token, implement exponential backoff
await applyExponentialDelay(storedToken?.attempts || 0);
return false;
}
// Verify token signature
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
return decoded;
} catch (err) {
// Increment failed attempts, implement lockout if needed
await db.tokens.updateOne(
{ _id: storedToken._id },
{ $inc: { attempts: 1 } }
);
if (storedToken.attempts > 10) {
await lockoutToken(storedToken._id);
}
return false;
}
}
Implement token complexity requirements:
// Generate cryptographically strong tokens
function generateSecureToken() {
const token = crypto.randomBytes(32).toString('base64url');
const expiresAt = Date.now() + 24 * 60 * 60 * 1000; // 24 hours
return {
token,
expiresAt,
hash: crypto.createHash('sha256').update(token).digest('hex')
};
}
Add monitoring and alerting for suspicious patterns:
// Monitor for potential brute force attempts
async function monitorBruteForceAttempts() {
const recentFailures = await db.authLogs.aggregate([
{ $match: { success: false, timestamp: { $gte: new Date(Date.now() - 15 * 60000) } } },
{ $group: { _id: '$tokenHash', count: { $sum: 1 }, ips: { $addToSet: '$ip' } } },
{ $match: { count: { $gte: 10 }, ips: { $size: { $gte: 3 } } } }
]);
for (const attempt of recentFailures) {
await alertSecurityTeam({
type: 'potential_brute_force',
tokenHash: attempt._id,
attempts: attempt.count,
sourceIPs: attempt.ips,
timestamp: new Date()
});
}
}
Consider implementing token binding to specific client characteristics:
// Bind tokens to client fingerprint
function bindTokenToClient(token, clientInfo) {
const fingerprint = crypto.createHash('sha256')
.update(JSON.stringify({
userAgent: clientInfo.userAgent,
ip: clientInfo.ip,
acceptHeaders: clientInfo.acceptHeaders
}))
.digest('hex');
return `${token}.${fingerprint}`;
}
Frequently Asked Questions
How does middleBrick detect brute force vulnerabilities in Bearer Token implementations?
middleBrick performs black-box scanning by sending various token patterns to your endpoints and analyzing responses. The scanner tests malformed tokens, random strings, and common token formats to identify endpoints that lack proper rate limiting or validation. It checks for consistent response times regardless of token validity, missing rate limiting mechanisms, and endpoints that reveal token existence information through timing or error messages.
What's the difference between IP-based and token-based rate limiting for Bearer Tokens?
IP-based rate limiting restricts requests by client IP address, which fails against distributed attacks and shared networks. Token-based rate limiting restricts requests by the token value itself, limiting how many requests a specific token can make regardless of the source IP. This approach is more effective against Bearer Token brute force attacks because attackers often use distributed networks and because legitimate users share networks. Token-based limiting can be implemented using Redis or similar stores to track token usage patterns across your infrastructure.