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