Brute Force and Credential Stuffing
Brute Force and Credential Stuffing
Authentication endpoints face constant automated attacks attempting to guess passwords or use credentials leaked from other breaches. Firewall-based defenses focus on detecting and blocking attack patterns rather than validating credentials.
Implement intelligent brute force protection:
# Advanced brute force detection
class BruteForceProtector:
def __init__(self):
self.attempt_tracker = {}
self.blocked_ips = set()
self.credential_patterns = {}
def track_login_attempt(self, ip, username, success, user_agent):
current_time = time.time()
# Initialize tracking for new IPs
if ip not in self.attempt_tracker:
self.attempt_tracker[ip] = {
'attempts': [],
'usernames': set(),
'user_agents': set(),
'success_count': 0,
'fail_count': 0
}
tracker = self.attempt_tracker[ip]
tracker['attempts'].append({
'time': current_time,
'username': username,
'success': success,
'user_agent': user_agent
})
# Update counters
if success:
tracker['success_count'] += 1
else:
tracker['fail_count'] += 1
tracker['usernames'].add(username)
tracker['user_agents'].add(user_agent)
# Clean old attempts (keep last hour)
tracker['attempts'] = [a for a in tracker['attempts']
if current_time - a['time'] < 3600]
# Detect attack patterns
attack_score = self.calculate_attack_score(tracker)
if attack_score > 100:
self.block_ip(ip, f"Attack score: {attack_score}")
return 'blocked'
return 'monitored'
def calculate_attack_score(self, tracker):
score = 0
recent_attempts = [a for a in tracker['attempts']
if time.time() - a['time'] < 300] # Last 5 minutes
# High failure rate
if len(recent_attempts) > 5:
fail_rate = sum(1 for a in recent_attempts if not a['success']) / len(recent_attempts)
if fail_rate > 0.8:
score += 50
# Multiple usernames (credential spraying)
if len(tracker['usernames']) > 10:
score += 30
# Rapid attempts
if len(recent_attempts) > 20:
score += 40
# Multiple user agents (distributed attack)
if len(tracker['user_agents']) > 5:
score += 20
# Known bad patterns
for username in tracker['usernames']:
if username.lower() in ['admin', 'root', 'administrator', 'test']:
score += 10
return score