Saltar al contenido

Verificación Estricta de Content-Type

Por defecto, FastAPI usa verificación estricta del header Content-Type para los bodies de peticiones JSON, esto significa que las peticiones JSON deben incluir un header Content-Type válido (ej. application/json) para que el body sea procesado como JSON.

Riesgo CSRF

Este comportamiento por defecto proporciona protección contra una clase de ataques de Cross-Site Request Forgery (CSRF) en un escenario muy específico.

Estos ataques explotan el hecho de que los navegadores permiten a los scripts enviar peticiones sin hacer ninguna verificación CORS preflight cuando:

  • no tienen un header Content-Type (ej. usando fetch() con un body Blob)
  • y no envían ninguna credencial de autenticación.

Este tipo de ataque es principalmente relevante cuando:

  • la aplicación se está ejecutando localmente (ej. en localhost) o en una red interna
  • y la aplicación no tiene ninguna autenticación, espera que cualquier petición de la misma red pueda ser confiable.

Ejemplo de Ataque

Imagina que construyes una forma de ejecutar un agente de AI local.

Proporciona una API en

http://localhost:8000/v1/agents/multivac

También hay un frontend en

http://localhost:8000

Consejo

Ten en cuenta que ambos tienen el mismo host.

Luego usando el frontend puedes hacer que el agente de AI haga cosas en tu nombre.

Como se está ejecutando localmente, y no en el internet abierto, decides no tener ninguna autenticación configurada, simplemente confiar en el acceso a la red local.

Luego uno de tus usuarios podría instalarlo y ejecutarlo localmente.

Luego podrían abrir un sitio web malicioso, ej. algo como

https://evilhackers.example.com

Y ese sitio web malicioso envía peticiones usando fetch() con un body Blob a la API local en

http://localhost:8000/v1/agents/multivac

A pesar de que el host del sitio web malicioso y de la app local son diferentes, el navegador no activará una petición CORS preflight porque:

  • Se está ejecutando sin ninguna autenticación, no tiene que enviar ninguna credencial.
  • El navegador cree que no está enviando JSON (porque falta el header Content-Type).

Entonces el sitio web malicioso podría hacer que el agente de AI local envíe mensajes enojados al ex-jefe del usuario... o peor. 😅

Internet Abierto

Si tu app está en el internet abierto, no "confiarías en la red" y dejarías a cualquiera enviar peticiones privilegiadas sin autenticación.

Los atacantes podrían simplemente ejecutar un script para enviar peticiones a tu API, sin necesidad de interacción del navegador, así que probablemente ya estás asegurando cualquier endpoint privilegiado.

En ese caso este ataque / riesgo no te aplica.

Este riesgo y ataque es principalmente relevante cuando la app se ejecuta en la red local y esa es la única protección asumida.

Permitir Peticiones Sin Content-Type

Si necesitas soportar clientes que no envían un header Content-Type, puedes deshabilitar la verificación estricta estableciendo strict_content_type=False:

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI(strict_content_type=False)


class Item(BaseModel):
    name: str
    price: float


@app.post("/items/")
async def create_item(item: Item):
    return item

Con esta configuración, las peticiones sin un header Content-Type tendrán su body procesado como JSON, que es el mismo comportamiento que en versiones anteriores de FastAPI.

Nota

Este comportamiento y configuración fue añadido en FastAPI 0.132.0.