HIGH password sprayingbearer tokens

Password Spraying with Bearer Tokens

How Password Spraying Manifests in Bearer Tokens

Password spraying with Bearer tokens exploits the fundamental trust model of token-based authentication. Unlike traditional password spraying where attackers try common passwords across many accounts, Bearer token spraying targets the token validation mechanism itself.

The attack typically begins with an attacker obtaining a valid token through various means—phishing, network interception, or purchasing from dark markets. The attacker then systematically tests this token against numerous API endpoints to map out functionality and identify privileged operations. Since Bearer tokens are often scoped too broadly, a single token might grant access to administrative functions, user data modification, or system configuration.

A common manifestation involves automated scripts cycling through a list of API endpoints with the same stolen token. For example:

import requests

def spray_token(token, endpoints):
    headers = {'Authorization': f'Bearer {token}'}
    results = []
    
    for endpoint in endpoints:
        try:
            response = requests.get(endpoint, headers=headers, timeout=5)
            results.append({
                'endpoint': endpoint,
                'status_code': response.status_code,
                'response_size': len(response.content)
            })
        except requests.exceptions.RequestException:
            results.append({
                'endpoint': endpoint,
                'status_code': 'timeout',
                'response_size': 0
            })
    
    return results

# Common admin endpoints attackers target
admin_endpoints = [
    'https://api.example.com/admin/users',
    'https://api.example.com/admin/config',
    'https://api.example.com/admin/logs',
    'https://api.example.com/admin/backup'
]

stolen_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
results = spray_token(stolen_token, admin_endpoints)

The severity of Bearer token spraying lies in its silent nature. Unlike password-based attacks that trigger account lockouts, token spraying often goes undetected because the token remains valid throughout the attack. Attackers can map entire API surfaces without triggering traditional security mechanisms.

Another variant involves token replay across different services. Many organizations use the same token format across multiple microservices. An attacker who obtains a token valid for one service can systematically test it against others, potentially gaining broader access than intended. This cross-service token spraying is particularly dangerous in microservice architectures where service-to-service authentication relies on shared token validation logic.

Bearer Tokens-Specific Detection

Detecting Bearer token spraying requires monitoring patterns that traditional authentication systems miss. The key is identifying abnormal token usage patterns rather than just failed authentication attempts.

Effective detection starts with token usage analytics. Track the number of unique endpoints accessed per token over time windows. A legitimate user typically accesses a predictable subset of endpoints. When a single token suddenly accesses dozens of unique endpoints across different functional areas, it signals potential spraying activity.

from collections import defaultdict
import time

class TokenUsageMonitor:
    def __init__(self):
        self.token_activity = defaultdict(list)  # token -> [(timestamp, endpoint)]
        self.window_seconds = 300  # 5 minute window
    
    def record_access(self, token, endpoint):
        now = time.time()
        self.token_activity[token].append((now, endpoint))
        
        # Clean old entries
        self.token_activity[token] = [
            (ts, ep) for ts, ep in self.token_activity[token] 
            if ts > now - self.window_seconds
        ]
    
    def detect_spraying(self):
        suspicious_tokens = []
        
        for token, accesses in self.token_activity.items():
            unique_endpoints = len(set(ep for ts, ep in accesses))
            
            if unique_endpoints > 20:  # Threshold: more than 20 unique endpoints
                suspicious_tokens.append({
                    'token': token,
                    'unique_endpoints': unique_endpoints,
                    'access_count': len(accesses)
                })
        
        return suspicious_tokens

monitor = TokenUsageMonitor()
# During request processing:
# monitor.record_access(incoming_token, request.path)

Rate limiting at the token level provides another defense layer. Unlike user-based rate limiting, token-based limits track how many requests a specific token makes regardless of the user identity. This catches scenarios where a single token is being actively sprayed across multiple endpoints.

middleBrick's scanning approach specifically targets Bearer token vulnerabilities through unauthenticated black-box testing. The scanner attempts to identify endpoints that accept tokens without proper scope validation, testing common token formats against administrative paths. middleBrick's LLM security module also checks for AI-specific token spraying patterns in LLM endpoints, where system prompt injection can be achieved through token manipulation.

Network-level detection complements application monitoring. Look for traffic patterns showing a single IP rapidly cycling through API endpoints with consistent Authorization headers. This external view catches spraying attempts before they reach application logic.

Bearer Tokens-Specific Remediation

Remediating Bearer token spraying requires architectural changes to how tokens are issued, validated, and scoped. The goal is to minimize the blast radius of any single token compromise.

Implement token scope limitations at issuance. Rather than issuing monolithic tokens with broad permissions, create scoped tokens that grant access only to specific API groups. This follows the principle of least privilege and contains spraying damage.

from datetime import datetime, timedelta
from jose import jwt

def create_scoped_token(user_id, allowed_endpoints):
    # allowed_endpoints: list of endpoint patterns this token can access
    payload = {
        'user_id': user_id,
        'scope': {
            'allowed_endpoints': allowed_endpoints,
            'issued_at': datetime.utcnow().isoformat()
        },
        'exp': datetime.utcnow() + timedelta(hours=1),
        'iat': datetime.utcnow()
    }
    
    token = jwt.encode(payload, 'your-secret-key', algorithm='HS256')
    return token

# Issue a token only for specific functionality
admin_token = create_scoped_token(
    user_id=123,
    allowed_endpoints=['/admin/users/*', '/admin/reports/*']
)

user_token = create_scoped_token(
    user_id=123,
    allowed_endpoints=['/user/profile', '/user/orders']
)

Implement token introspection at each endpoint. Before processing requests, validate that the token is permitted for the specific endpoint being accessed. This prevents tokens from being reused across unintended API surfaces.

from functools import wraps
from jose import jwt

def token_required(allowed_endpoints):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            auth_header = request.headers.get('Authorization')
            if not auth_header or not auth_header.startswith('Bearer '):
                return {'message': 'Token missing'}, 401
            
            token = auth_header.split(' ')[1]
            
            try:
                payload = jwt.decode(token, 'your-secret-key', algorithms=['HS256'])
                current_endpoint = request.path
                
                # Check if endpoint is in allowed scopes
                if not any(pattern in current_endpoint for pattern in 
                          payload.get('scope', {}).get('allowed_endpoints', [])):
                    return {'message': 'Token not authorized for this endpoint'}, 403
                    
            except jwt.ExpiredSignatureError:
                return {'message': 'Token expired'}, 401
            except jwt.JWTError:
                return {'message': 'Token invalid'}, 401
            
            return f(*args, **kwargs)
        
        return decorated_function
    
    return decorator

@app.route('/admin/users', methods=['GET'])
@token_required(allowed_endpoints=['/admin/users/*'])
def get_users():
    # Only tokens with /admin/users/* scope can access
    return jsonify(get_all_users())

Implement token rotation policies. Short-lived tokens (5-15 minutes) combined with refresh token mechanisms limit the window for successful spraying attacks. Even if an attacker obtains a token, it becomes invalid before comprehensive spraying can occur.

middleBrick's continuous monitoring in Pro tier helps validate these remediation efforts by regularly scanning your APIs for token validation weaknesses. The scanner tests whether tokens can be reused across unintended endpoints and whether scope validation is properly implemented.

Frequently Asked Questions

How does Bearer token spraying differ from traditional password spraying?
Traditional password spraying attempts common passwords across many user accounts, often triggering account lockouts. Bearer token spraying uses a single valid token to systematically probe multiple API endpoints. Since the token remains valid, attackers can map entire API surfaces without triggering traditional authentication defenses. The attack is silent and can continue until the token expires or is revoked.
Can middleBrick detect if my API is vulnerable to Bearer token spraying?
Yes. middleBrick's black-box scanning tests your API endpoints without requiring credentials. It identifies endpoints that accept tokens without proper scope validation, tests common token formats against administrative paths, and checks for cross-service token reuse vulnerabilities. The scanner specifically looks for patterns where a single token can access multiple functional areas it shouldn't have permission for.