Brute Force Attack in Fastapi with Dynamodb
Brute Force Attack in Fastapi with Dynamodb — how this specific combination creates or exposes the vulnerability
A brute force attack against a FastAPI service backed by DynamoDB typically targets authentication or account enumeration endpoints. In this combination, FastAPI provides the HTTP interface and request handling, while DynamoDB serves as the identity or session store. If login or password-reset endpoints do not enforce strict rate limiting and do not obscure whether a username exists, an attacker can iterate through usernames or passwords and observe differences in response behavior or timing.
Consider a typical FastAPI login route that queries DynamoDB to validate credentials:
import time
import boto3
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
app = FastAPI()
ddb = boto3.resource('dynamodb', region_name='us-east-1')
table = ddb.Table('users')
class LoginRequest(BaseModel):
username: str
password: str
def get_user(username: str):
resp = table.get_item(Key={'username': username})
return resp.get('Item')
@app.post('/login')
async def login(payload: LoginRequest):
user = get_user(payload.username)
if not user:
time.sleep(0.5) # naive attempt to avoid timing leaks
raise HTTPException(status_code=401, detail='Invalid credentials')
# password verification omitted for brevity
return {'status': 'ok'}
This pattern exposes two issues relevant to brute force:
- Account enumeration: The response indicates whether a username exists, enabling attackers to build a valid username list before attempting passwords.
- Lack of rate limiting: Without request-level throttling, an attacker can submit many guesses per second, especially when using credential lists common in credential stuffing or password spraying.
DynamoDB itself does not enforce application-level rate limits; it simply stores and retrieves items. Therefore, the responsibility to throttle and detect abusive patterns sits with FastAPI and any fronting infrastructure. The scan checks for missing rate limiting controls and for endpoints that leak account existence, mapping findings to the Authentication and Rate Limiting categories from the 12 security checks.
In the context of middleBrick’s 12 parallel checks, the scan would flag the absence of per-user or global request throttling and would note inconsistent timing or messaging that can aid enumeration. Findings reference the OWASP API Top 10 (2023) category A07:2021 — Identification and Authentication Failures and align with common PCI-DSS and SOC2 control themes around access enforcement.
Dynamodb-Specific Remediation in Fastapi — concrete code fixes
Remediation focuses on reducing information leakage and introducing request-level controls while keeping DynamoDB as the backend store. The following FastAPI example demonstrates safer practices:
import hmac
import time
import boto3
from fastapi import FastAPI, HTTPException, Request, Depends
from pydantic import BaseModel
app = FastAPI()
ddb = boto3.resource('dynamodb', region_name='us-east-1')
table = ddb.Table('users')
class LoginRequest(BaseModel):
username: str
password: str
def safe_compare(a: str, b: str) -> bool:
return hmac.compare_digest(a.encode('utf-8'), b.encode('utf-8'))
def get_user(username: str):
resp = table.get_item(Key={'username': username})
return resp.get('Item')
@app.post('/login')
async def login(payload: LoginRequest, req: Request):
# Always perform the lookup to keep timing consistent
user = get_user(payload.username)
dummy_hash = '$2b$12$' + 'x' * 31 # dummy hash for absent users
stored = user.get('password_hash', dummy_hash) if user else dummy_hash
if not safe_compare(stored, '$2b$12$examplehashplaceholder'): # replace with real check
time.sleep(0.2) # constant delay to reduce timing differences
raise HTTPException(status_code=401, detail='Invalid credentials')
# Implement further verification and token issuance here
return {'status': 'ok'}
Key remediation steps illustrated:
- Consistent timing: Always perform the DynamoDB get_item, even when the username is not found, and use a constant-time comparison for passwords to avoid leaking existence via response time.
- Uniform error messages: Return the same generic message for invalid username or password to prevent account enumeration.
- Rate limiting: Apply a global or per-identifier throttle using middleware or an API gateway; DynamoDB does not provide this natively, so enforce it in FastAPI or at the edge.
For DynamoDB-specific hardening, ensure that usernames are indexed for efficient lookups and that auto-scaling is configured to handle bursts of legitimate traffic without triggering throttling that could be abused to degrade service. middleBrick’s scan will validate whether these controls are observable during the unauthenticated assessment, reporting findings under Authentication, Rate Limiting, and Data Exposure categories.