Перейти до змісту

Сувора перевірка Content-Type

🌐 Переклад ШІ та людьми

Цей переклад виконано ШІ під керівництвом людей. 🤝

Можливі помилки через неправильне розуміння початкового змісту або неприродні формулювання тощо. 🤖

Ви можете покращити цей переклад, допомігши нам краще спрямовувати AI LLM.

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

За замовчуванням FastAPI використовує сувору перевірку заголовка Content-Type для тіл запитів JSON, це означає, що запити JSON мають включати дійсний заголовок Content-Type (наприклад, application/json), щоб тіло було розібране як JSON.

Ризик CSRF

Ця поведінка за замовчуванням забезпечує захист від класу атак Cross-Site Request Forgery (CSRF) у дуже конкретному сценарії.

Ці атаки використовують той факт, що браузери дозволяють скриптам надсилати запити без виконання перевірки CORS preflight, коли вони:

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

Такий тип атаки головним чином актуальний, коли:

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

Приклад атаки

Уявіть, що ви створюєте спосіб запускати локального AI-агента.

Він надає API за адресою

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

Є також фронтенд за адресою

http://localhost:8000

Порада

Зауважте, що обидва мають один і той самий хост.

Використовуючи фронтенд, ви можете змушувати AI-агента виконувати дії від вашого імені.

Оскільки він працює локально, а не у відкритому інтернеті, ви вирішуєте не налаштовувати жодної автентифікації, просто покладаючись на доступ до локальної мережі.

Один із ваших користувачів може встановити його і запустити локально.

Потім він може відкрити шкідливий вебсайт, напр. щось на кшталт

https://evilhackers.example.com

І цей шкідливий вебсайт надсилає запити, використовуючи fetch() з тілом типу Blob, до локального API за адресою

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

Хоча хости шкідливого вебсайту та локального застосунку різні, браузер не запустить CORS preflight-запит, тому що:

  • Застосунок працює без будь-якої автентифікації, немає потреби надсилати облікові дані.
  • Браузер вважає, що він не надсилає JSON (через відсутній заголовок Content-Type).

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

Відкритий інтернет

Якщо ваш застосунок у відкритому інтернеті, ви не стали б «довіряти мережі» і дозволяти кому завгодно надсилати привілейовані запити без автентифікації.

Зловмисники можуть просто запустити скрипт, щоб надсилати запити до вашого 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.