Перейти к содержанию

Строгая проверка HTTP-заголовка Content-Type

🌐 Перевод выполнен с помощью ИИ и людей

Этот перевод был сделан ИИ под руководством людей. 🤝

В нем могут быть ошибки из-за неправильного понимания оригинального смысла или неестественности и т. д. 🤖

Вы можете улучшить этот перевод, помогая нам лучше направлять ИИ LLM.

Английская версия

По умолчанию FastAPI использует строгую проверку HTTP-заголовка Content-Type для JSON-тел запросов. Это означает, что JSON-запросы должны включать корректный заголовок Content-Type (например, application/json), чтобы тело запроса было обработано как JSON.

Риск CSRF

Такое поведение по умолчанию обеспечивает защиту от класса атак Cross-Site Request Forgery (CSRF) в очень специфическом сценарии.

Эти атаки используют то, что браузеры позволяют скриптам отправлять запросы без выполнения CORS preflight, когда они:

  • не имеют заголовка Content-Type (например, при использовании fetch() с телом Blob)
  • и не отправляют никаких учетных данных аутентификации.

Этот тип атак в основном актуален, когда:

  • приложение запускается локально (например, на localhost) или во внутренней сети
  • и в приложении нет аутентификации, оно предполагает, что любому запросу из той же сети можно доверять.

Пример атаки

Представьте, что вы сделали способ запускать локального ИИ-агента.

Он предоставляет API по адресу

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

Есть также фронтенд по адресу

http://localhost:8000

Совет

Обратите внимание, что у обоих один и тот же хост.

Через фронтенд вы можете заставлять ИИ-агента выполнять действия от вашего имени.

Так как он работает локально и не в открытом интернете, вы решаете не настраивать аутентификацию, полагаясь на доступ к локальной сети.

Затем один из ваших пользователей может установить это и запускать локально.

Потом он может открыть вредоносный сайт, например что-то вроде

https://evilhackers.example.com

И этот вредоносный сайт отправит запросы с помощью fetch() с телом Blob к локальному API по адресу

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

Несмотря на то, что хост вредоносного сайта и локального приложения различается, браузер не запустит CORS preflight-запрос, потому что:

  • Приложение работает без аутентификации, ему не нужно отправлять какие-либо учетные данные.
  • Браузер «считает», что он не отправляет JSON (из-за отсутствия заголовка Content-Type).

В итоге вредоносный сайт может заставить локального ИИ-агента отправить злые сообщения бывшему начальнику пользователя... или что-то похуже. 😅

Открытый интернет

Если ваше приложение доступно в открытом интернете, вы не будете «доверять сети» и позволять кому угодно отправлять привилегированные запросы без аутентификации.

Злоумышленники могут просто запустить скрипт и слать запросы к вашему API, без участия браузера, так что вы, вероятно, уже защищаете любые привилегированные эндпоинты.

В этом случае эта атака/риск на вас не распространяется.

Этот риск и атака в основном актуальны, когда приложение работает в локальной сети и это единственная предполагаемая защита.

Разрешение запросов без Content-Type

Если вам нужно поддерживать клиентов, которые не отправляют заголовок Content-Type, вы можете отключить строгую проверку, установив 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

С этой настройкой запросы без заголовка Content-Type будут иметь тело запроса, обработанное как JSON — это такое же поведение, как в более старых версиях FastAPI.

Информация

Это поведение и настройка были добавлены в FastAPI 0.132.0.