Security Misconfiguration

How to Fix Security Misconfiguration in FastAPI March 2026 [CVE-2021-32677]

[Updated March 2026] Updated CVE-2021-32677

Overview

CVE-2021-32677 describes a security misconfiguration in FastAPI where, in versions lower than 0.65.2, endpoints that used cookies for authentication and received JSON payloads could be exploited via CSRF. FastAPI would read the request body as JSON even if the Content-Type header did not indicate JSON (for example text/plain), and such requests are considered Simple Requests that bypass certain CORS preflight checks. An attacker could lure a victim into submitting a crafted request from a malicious site, using the victim's cookies, to perform unintended actions. The issue is mitigated by upgrading to FastAPI 0.65.2 or later, where JSON parsing only occurs when the Content-Type is an allowed JSON type. If upgrading is not possible, you can introduce a middleware or endpoint-level check to enforce JSON content types as a mitigation.

Affected Versions

FastAPI < 0.65.2

Code Fix Example

FastAPI API Security Remediation
# Vulnerable pattern and the fix side-by-side in a single snippet
from fastapi import FastAPI, Request, HTTPException

# Vulnerable app: reads JSON payload regardless of Content-Type
app_vuln = FastAPI()

@app_vuln.post("/vulnerable-action")
async def vulnerable_action(req: Request):
    # Potential CSRF risk: parsing JSON from requests with non-JSON Content-Type (e.g., text/plain)
    data = await req.json()
    return {"status": "ok", "data": data}

# Fixed app: validates Content-Type before parsing JSON
app_fix = FastAPI()

def is_json_content_type(headers) -> bool:
    ctype = headers.get("content-type", "").lower()
    # Accept common JSON media types
    return (
        ctype.startswith("application/json") or
        ctype.startswith("application/geo+json") or
        ctype.startswith("application/json-patch+json")
    )

@app_fix.post("/secure-action")
async def secure_action(req: Request):
    if not is_json_content_type(req.headers):
        raise HTTPException(status_code=415, detail="Unsupported Media Type")
    data = await req.json()
    return {"status": "ok", "data": data}

CVE References

Choose which optional cookies to allow. You can change this any time.