CVE-2021-32677
📋 TL;DR
FastAPI versions below 0.65.2 are vulnerable to CSRF attacks when using cookie-based authentication with JSON payloads. The vulnerability allows attackers to bypass CORS protections by sending requests with text/plain content-type containing JSON data, which FastAPI incorrectly parses. This affects any FastAPI application using cookie authentication that accepts JSON payloads.
💻 Affected Systems
- FastAPI
📦 What is this software?
Fastapi by Tiangolo
Fedora by Fedoraproject
⚠️ Risk & Real-World Impact
Worst Case
Attackers can perform unauthorized actions on behalf of authenticated users, potentially leading to data theft, account takeover, or system compromise.
Likely Case
Unauthorized API calls leading to data manipulation, privilege escalation, or information disclosure.
If Mitigated
Limited impact with proper CSRF tokens, same-origin policies, or content-type validation in place.
🎯 Exploit Status
Exploitation requires the victim to be authenticated and visit a malicious site. The attack leverages browser behavior with text/plain content-type to bypass CORS preflight checks.
🛠️ Fix & Mitigation
✅ Official Fix
Patch Version: 0.65.2
Vendor Advisory: https://github.com/tiangolo/fastapi/security/advisories/GHSA-8h2j-cgx8-6xv7
Restart Required: Yes
Instructions:
1. Update FastAPI: pip install fastapi==0.65.2 or higher
2. Restart your FastAPI application
3. Verify the update with: pip show fastapi
🔧 Temporary Workarounds
Content-Type Validation Middleware
allAdd middleware to reject requests with non-JSON content-type headers before JSON parsing occurs.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware
class ContentTypeMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
content_type = request.headers.get('content-type', '')
if request.method in ['POST', 'PUT', 'PATCH'] and 'application/json' not in content_type and 'application/geo+json' not in content_type:
return JSONResponse(status_code=415, content={'detail': 'Unsupported Media Type'})
return await call_next(request)
app = FastAPI()
app.add_middleware(ContentTypeMiddleware)
🧯 If You Can't Patch
- Implement CSRF tokens for all state-changing endpoints
- Use token-based authentication (Bearer tokens) instead of cookie-based authentication
🔍 How to Verify
Check if Vulnerable:
Check FastAPI version: pip show fastapi | grep Version. If version is below 0.65.2 and application uses cookie authentication with JSON endpoints, it's vulnerable.
Check Version:
pip show fastapi | grep Version
Verify Fix Applied:
After updating to 0.65.2+, test that requests with text/plain content-type containing JSON are rejected with 415 status code.
📡 Detection & Monitoring
Log Indicators:
- 415 Unsupported Media Type errors for text/plain requests to JSON endpoints
- Unexpected successful JSON parsing with non-JSON content-type headers
Network Indicators:
- POST/PUT/PATCH requests with text/plain content-type to JSON endpoints
- Cross-origin requests with cookie authentication
SIEM Query:
content_type:"text/plain" AND (method:POST OR method:PUT OR method:PATCH) AND status:200 AND path:"/api/*"
🔗 References
- https://github.com/tiangolo/fastapi/commit/fa7e3c996edf2d5482fff8f9d890ac2390dede4d
- https://github.com/tiangolo/fastapi/security/advisories/GHSA-8h2j-cgx8-6xv7
- https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/MATAWX25TYKNEKLDMKWNLYDB34UWTROA/
- https://github.com/tiangolo/fastapi/commit/fa7e3c996edf2d5482fff8f9d890ac2390dede4d
- https://github.com/tiangolo/fastapi/security/advisories/GHSA-8h2j-cgx8-6xv7
- https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/MATAWX25TYKNEKLDMKWNLYDB34UWTROA/