Overview
The CVE-2021-32677 case shows how FastAPI versions < 0.65.2 could mis-handle incoming requests by reading the request payload as JSON even when the Content-Type header was not a JSON type. This could enable CSRF attacks in cookies-based auth scenarios and, more broadly, lead to Unrestricted Resource Consumption because an attacker can prompt the server to parse large or crafted payloads that aren’t actually JSON, consuming CPU and memory. In practice, a browser could submit a request with content-type text/plain containing JSON data, which FastAPI would still attempt to parse as JSON. Since text/plain requests are not always subjected to CORS preflight, the browser could send authenticated requests (with cookies) without triggering the normal CSRF safeguards. This vulnerability was fixed in FastAPI 0.65.2, which only parses JSON when the content-type is application/json or other JSON-compatible media types (e.g., application/geo+json). The Unrestricted Resource Consumption risk here arises from parsing and processing potentially large or crafted payloads under conditions where the request should have been rejected early due to an incorrect content-type.
Affected Versions
< 0.65.2
Code Fix Example
FastAPI API Security Remediation
Vulnerable:
from fastapi import FastAPI, Request
app = FastAPI()
@app.post('/data')
async def data(req: Request):
payload = await req.json() # this would parse JSON even if content-type isn't application/json
# process payload
return {'ok': True}
# Fixed:
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
app = FastAPI()
def is_json_content_type(req: Request) -> bool:
ct = (req.headers.get('content-type') or '').lower()
return ct.startswith('application/json') or '+json' in ct
@app.post('/data')
async def data_fixed(req: Request):
if not is_json_content_type(req):
raise HTTPException(status_code=415, detail='Unsupported Media Type')
payload = await req.json() # safe to parse now that content-type is JSON
# process payload
return {'ok': True}