Cross Site Request Forgery in Fastapi
How Cross Site Request Forgery Manifests in Fastapi
Cross Site Request Forgery (CSRF) in Fastapi applications exploits the fact that browsers automatically include cookies and authentication headers when making requests to a domain. An attacker crafts a malicious website that, when visited by an authenticated user, triggers unwanted actions on the Fastapi backend without the user's knowledge or consent.
Consider a Fastapi endpoint that processes payments:
from fastapi import FastAPI, Form, Request
app = FastAPI()
@app.post("/transfer")
async def transfer_funds(
request: Request,
from_account: str = Form(...),
to_account: str = Form(...),
amount: float = Form(...)
):
# No CSRF protection
# Process transfer logic here
return {"status": "success"}
An attacker could create a malicious page that automatically submits this form:
<form id="csrf-form" action="https://your-fastapi-app.com/transfer" method="POST" style="display:none;">
<input type="hidden" name="from_account" value="victim-account">
<input type="hidden" name="to_account" value="attacker-account">
<input type="hidden" name="amount" value="1000">
</form>
<script>document.getElementById('csrf-form').submit();</script>
When an authenticated user visits this page, their browser automatically sends cookies and any stored authentication tokens to the Fastapi backend, causing the unauthorized transfer to execute.
Fastapi's async nature doesn't prevent CSRF attacks. The vulnerability exists in the authentication mechanism and endpoint design, not in the framework's concurrency model. Any endpoint that performs state-changing operations without CSRF protection is vulnerable, regardless of whether it uses synchronous or asynchronous code.
Common Fastapi CSRF targets include:
- Payment processing endpoints
- User account modifications (email, password changes)
- Administrative actions (user deletion, role changes)
- Financial transactions (transfers, deposits, withdrawals)
- Configuration changes
The risk is particularly high in Fastapi applications that rely solely on session cookies or JWT tokens stored in cookies, as these are automatically included in cross-origin requests by browsers.
Fastapi-Specific Detection
Detecting CSRF vulnerabilities in Fastapi requires both manual code review and automated scanning. middleBrick's black-box scanning approach is particularly effective for Fastapi applications since it tests the actual runtime behavior without requiring source code access.
middleBrick scans Fastapi endpoints for CSRF vulnerabilities by:
- Identifying state-changing HTTP methods (POST, PUT, PATCH, DELETE) that lack anti-CSRF tokens
- Testing for cookie-based authentication patterns
- Checking for missing SameSite cookie attributes
- Verifying the presence of CSRF middleware or protection mechanisms
The scanner tests each endpoint by attempting to submit requests with forged origins and examining the server's response. For Fastapi applications, middleBrick specifically looks for:
{
"csrf_vulnerabilities": {
"endpoint": "/api/transfer",
"method": "POST",
"risk_level": "high",
"evidence": "No anti-CSRF token found, accepts requests from any origin",
"recommendation": "Implement CSRF protection using Fastapi's middleware or add SameSite cookie attributes"
}
}middleBrick's scanning process takes 5-15 seconds and provides a security risk score (A-F) with specific findings for each vulnerability category. The tool tests the unauthenticated attack surface, making it ideal for identifying CSRF vulnerabilities that could be exploited by external attackers.
For manual detection in Fastapi codebases, look for these patterns:
# Vulnerable pattern - no CSRF protection
@app.post("/sensitive-action")
async def sensitive_action(
request: Request,
data: dict = Form(...)
):
# Process sensitive action without verification
return {"result": "processed"}
middleBrick's GitHub Action integration allows you to automatically scan Fastapi APIs in your CI/CD pipeline, failing builds if CSRF vulnerabilities are detected before deployment to production.
Fastapi-Specific Remediation
Fastapi provides several approaches to mitigate CSRF vulnerabilities. The most effective solution combines anti-CSRF tokens with proper cookie configuration.
Using Fastapi's built-in middleware for CSRF protection:
from fastapi import FastAPI, Request, Form, Depends
from fastapi.middleware import Middleware
from fastapi.middleware.csrf import CSRFMiddleware
app = FastAPI(middleware=[
Middleware(CSRFMiddleware)
])
@app.post("/protected-endpoint")
async def protected_endpoint(
csrf_token: str = Depends(CSRFMiddleware.csrf_cookie)
):
# CSRF token is automatically validated
return {"status": "protected"}
For applications using JWT tokens stored in cookies, implement SameSite attributes:
from fastapi import FastAPI, Response
from datetime import datetime, timedelta
import jwt
app = FastAPI()
SECRET_KEY = "your-secret-key"
async def create_jwt_token(response: Response, user_id: str):
expire = datetime.utcnow() + timedelta(hours=1)
token = jwt.encode({
"sub": user_id,
"exp": expire
}, SECRET_KEY, algorithm="HS256")
response.set_cookie(
key="access_token",
value=token,
httponly=True,
samesite="Strict", # Prevents CSRF
max_age=3600
)
Alternative approach using double-submit cookie pattern:
from fastapi import FastAPI, Request, Form, Depends
from fastapi.middleware import Middleware
from fastapi.middleware.csrf import CSRFMiddleware
import secrets
import hashlib
app = FastAPI(middleware=[Middleware(CSRFMiddleware)])
async def get_csrf_token(request: Request):
token = request.state.get("csrf_token")
if not token:
token = secrets.token_urlsafe(32)
request.state.csrf_token = token
return token
@app.post("/transfer")
async def transfer_funds(
csrf_token: str = Depends(get_csrf_token),
from_account: str = Form(...),
to_account: str = Form(...),
amount: float = Form(...)
):
# Verify CSRF token matches cookie
if request.cookies.get("csrf_token") != csrf_token:
raise HTTPException(status_code=403, detail="CSRF token mismatch")
# Process transfer
return {"status": "transfer processed"}
For API-only Fastapi applications using JWT in Authorization headers, CSRF risk is minimal since browsers don't automatically include these headers in cross-origin requests. However, if you're using cookie-based authentication for your Fastapi API, implement one of the above protections.
middleBrick's continuous monitoring in the Pro plan can alert you if CSRF protections are accidentally removed during code changes, ensuring your Fastapi application remains secure over time.