Сувора перевірка 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.