Шарова безпека в Django: чому ALLOWED_HOSTS, CORS та CSRF мають вирішальне значення

У світі, де атаки та вразливості швидко еволюціонують, захист веб-застосунку вимагає уваги до кількох критичних моментів. У Django три налаштування зазвичай виділяються: ALLOWED_HOSTS, CORS та CSRF. Але це не просто чергові пункти в списку розробника — вони складають багатошарову оборону від загроз, починаючи від некоректної конфігурації доменів до зловмисних прихованих запитів.

У цій статті ми розглянемо, як кожне з цих налаштувань сприяє безпеці, чому вони доповнюють одне одного і що ви можете зробити, щоб уникнути поширених помилок. Більше, ніж просто вивчення технічних термінів, ви зрозумієте, чому кожне налаштування є важливою частиною головоломки безпеки, яка захищає ваших користувачів і ваші дані.

1. ALLOWED_HOSTS

Що таке ALLOWED_HOSTS?

У файлі settings.py Django, налаштування ALLOWED_HOSTS визначає список доменних імен, на які ваш Django сайт може обробляти запити. Це, по суті, список дозволених доменів, який дозволяє вашому застосунку відповідати тільки на запити, зроблені до цих вказаних доменів.

Що робить і не робить ALLOWED_HOSTS

  • Що воно робить: перевірка домену. Це гарантує, що вхідні HTTP запити направляються на правильний домен, який ви вказали. Наприклад, якщо ви додали example.com до ALLOWED_HOSTS, Django прийме запити на example.com, але відхилить запити до malicious.com.
  • Що воно не робить: не захищає від CSRF. ALLOWED_HOSTS не перевіряє джерело запиту. Воно перевіряє лише домен призначення, що означає, що не захищає від атак міжсайтової підробки запитів (CSRF).
  • Без контролю CORS: Воно не регулює, які зовнішні домени можуть взаємодіяти з вашим API через JavaScript.

Практичний приклад

Припустимо, ви встановили ALLOWED_HOSTS = ['example.com']. Будь-який запит, що претендує на те, щоб бути для example.com, буде оброблений, незалежно від того, звідки він надійшов. Це означає, що хоча ALLOWED_HOSTS блокує запити на несанкціоновані домени, воно не зупиняє зловмисні сайти від відправлення запитів на example.com, якщо вони можуть підробити заголовок Host.

Django перевіряє заголовок HTTP Host кожного вхідного запиту і порівнює його з переліком доменів, вказаних у ALLOWED_HOSTS. Якщо DEBUG встановлено в False і домен не співпадає з жодним дозволеним, Django викликає помилку DisallowedHost (повертаючи відповідь 400). Ви також можете використовувати шаблони, такі як '.example.com', щоб дозволити всі піддомени example.com. Пам'ятайте, що хоча ALLOWED_HOSTS запобігає відповіді вашого застосунку на невідомі домени, воно не заміняє налаштування CSRF чи CORS; воно просто підтверджує, що запити адресовані на домен, який ви явно визнаєте.

2. CORS

Що таке CORS?

CORS (Cross-Origin Resource Sharing) — це функція безпеки, реалізована браузерами, яка контролює, як веб-застосунки взаємодіють з ресурсами з різних джерел (доменів). Вона визначає, які домени можуть надсилати запити до вашого API через JavaScript.

Що робить і не робить CORS

  • Що воно робить: контроль джерела. Налаштування CORS визначають, які зовнішні домени можуть надсилати запити до вашого API. Наприклад, якщо ви налаштуєте CORS для дозволу frontend.com, лише скрипти, що виконуються на frontend.com, можуть взаємодіяти з вашим API.
  • Що воно не робить: неповний захист від CSRF. CORS виконується браузерами, тому не захищає від атак на серверній стороні. Зловмисник може обійти CORS, роблячи запити безпосередньо зі свого сервера, ігноруючи обмеження браузера.
  • Без захисту даних: Воно не запобігає несанкціонованому доступу до даних через інші не-JavaScript засоби.

Практичний приклад

Якщо ви не налаштували CORS, фронтенд, розміщений на frontend.com, не зможе взаємодіяти з вашим API на api.example.com. Як тільки ви налаштуєте CORS для дозволу frontend.com, JavaScript, що виконується на frontend.com, зможе робити запити до вашого API.
Однак це не заважає комусь відправляти запити до вашого API-сервера безпосередньо з іншого серверу.

За замовчуванням Django не застосовує правила Cross-Origin Resource Sharing (CORS); більшість розробників використовують бібліотеку django-cors-headers. Коли запит надходить, проміжне програмне забезпечення перевіряє заголовок Origin, щоб побачити, чи відповідає він будь-якому з дозволених джерел, зазначених у налаштуваннях Django (наприклад, CORS_ALLOWED_ORIGINS). Якщо це співпадає, проміжне програмне забезпечення встановлює відповідні заголовки відповіді, такі як Access-Control-Allow-Origin, щоб браузери дозволяли JavaScript запити з цих доменів. Якщо джерело не входить до списку дозволених доменів, запит зазвичай блокується або позначається браузером. Зазначте, що CORS в основному захищає від несанкціонованих міждоменних запитів браузера і не запобігає викликам безпосередньо з серверу або атакам CSRF.

3. CSRF

Що таке CSRF?

CSRF (Cross-Site Request Forgery) — це тип атаки, коли зловмисні вебсайти вводять користувачів в оману, змушуючи їх виконувати небажані дії на довіреному сайті, на якому вони автентифіковані. Django надає вбудований захист від CSRF, використовуючи токени, які перевіряють легітимність запитів.

Як працює CSRF

Django генерує унікальний CSRF токен для кожної сесії користувача. Цей токен повинен бути включений у будь-які форми або запити, що змінюють стан (наприклад, POST, PUT, DELETE). Якщо запит не містить дійсного токену, Django відхиляє його, запобігаючи несанкціонованим діям.

Практичний приклад

Уявімо, що користувач увійшов в bank.com і відвідав зловмисний сайт evil.com. Без захисту від CSRF, evil.com міг би спробувати відправити POST-запит до bank.com/transfer для переміщення коштів, використовуючи автентифіковану сесію користувача. З увімкненим захистом CSRF, bank.com перевіряє наявність дійсного токену CSRF у запиті. Оскільки evil.com не може отримати цей токен, запит буде відхилений.

4. Чому вам потрібні всі три?

Кожен з цих заходів безпеки вирішує різні вразливості:

  • ALLOWED_HOSTS: Забезпечує, що ваш Django застосунок відповідає лише на запити, адресовані вашим вказаним доменам.
  • CORS: Контролює, які зовнішні домени можуть взаємодіяти з вашим API через JavaScript, додаючи додатковий рівень захисту для міждоменних запитів.
  • CSRF: Захищає від несанкціонованих запитів, що змінюють стан, перевіряючи легітимність вхідних запитів.

Сценарій комбінованого захисту

  1. ALLOWED_HOSTS: Перевіряє, що запит адресований вашому домену (example.com).
  2. CORS: Забезпечує, що лише схвалені зовнішні домени (наприклад, frontend.com) можуть робити JavaScript запити до вашого API.
  3. CSRF: Перевіряє, що запити, що змінюють стан, походять з легітимних форм або скриптів на вашому сайті.

Чому не достатньо тільки одного чи двох?

  • Залежність лише від ALLOWED_HOSTS: Не запобігає несанкціонованим діям з дозволених доменів або через серверні атаки.
  • Залежність лише від CORS: Не захищає від CSRF атак з дозволених доменів або обходу через сервер.
  • Залежність лише від CSRF: Не контролює, які зовнішні домени можуть взаємодіяти з вашим API, що може призвести до витоку чутливих GET кінцевих точок.

5. Коли CSRF може бути непотрібним

В певних архітектурах, зокрема при побудові розділених або безголових односторінкових застосунків (SPA), які взаємодіють з Django бекендом, захист від Cross-Site Request Forgery (CSRF) може бути непотрібним. Це в основному стосується випадків, коли ваше застосування використовує методи автентифікації на основі токенів, такі як JSON Web Tokens (JWT), які передаються явно в заголовках запитів замість зберігання в куках.

Автентифікація на основі токенів та CSRF: При автентифікації на основі токенів, токени включаються в заголовки (наприклад, Authorization: Bearer <token>) і не додаються автоматично до кожного HTTP запиту браузером. Це означає, що зловмисні сайти не можуть доступити чи маніпулювати цими заголовками у міждоменних запитах, ефективно зменшуючи ризик атак CSRF.
Оскільки токени повністю керуються на стороні клієнта і повинні бути навмисно включені в кожний запит, автоматичне включення куків — що є поширеним вектором для CSRF — не відбувається.

Розділені SPA та розгляд CSRF: У налаштуванні розділеного SPA, де фронтенд і бекенд розміщені на різних доменах або піддоменах і взаємодіють через API, традиційні уразливості CSRF значно знижуються при використанні автентифікації на основі токенів. Однак залишається критично важливим впровадження належних політик Cross-Origin Resource Sharing (CORS). CORS контролює, які зовнішні домени можуть взаємодіяти з вашим API через JavaScript, забезпечуючи, що тільки довірені джерела можуть робити запити до ваших бекенд-сервісів.

Основні заходи безпеки: Навіть якщо захист CSRF не є необхідним завдяки використанню автентифікації на основі токенів, інші заходи безпеки все одно повинні бути впроваджені:

  • Конфігурація CORS: Правильно налаштуйте CORS, щоб обмежити доступ до API довіреним доменам, запобігаючи несанкціонованому JavaScript доступу до вашого бекенду.
  • Безпечне зберігання токенів: Переконайтеся, що токени зберігаються безпечно на стороні клієнта, щоб захистити їх від уразливостей, таких як Cross-Site Scripting (XSS), які можуть скомпрометувати цілісність токенів.
  • Забезпечення HTTPS: Завжди надавайте ваш застосунок через HTTPS, щоб захистити токени та дані під час передачі від перехоплення або зміни.

6. Найкращі практики

  • Принцип мінімальних прав: Дозволяйте лише певним, довіреним доменам взаємодіяти з вашим API через CORS.
  • Комбінуйте заходи безпеки: Використовуйте ALLOWED_HOSTS, CORS та CSRF разом для покриття різних аспектів безпеки.
  • Регулярні аудити: Періодично переглядайте та оновлюйте налаштування безпеки, щоб адаптуватися до змінних вимог і загроз.

Висновок

Забезпечення безпеки Django-застосунку включає в себе кілька рівнів, кожен з яких вирішує різні потенційні уразливості:

  • ALLOWED_HOSTS гарантує, що ваш застосунок відповідає тільки на запити, адресовані до ваших легітимних доменів.
  • CORS контролює, які зовнішні домени можуть робити JavaScript запити до вашого API.
  • CSRF захищає від несанкціонованих запитів, що змінюють стан, від автентифікованих користувачів.

pic

Впроваджуючи всі три заходи, ви створюєте надійний механізм безпеки, що захищає від широкого спектру атак. Пам'ятайте, що безпека — це багатошарова система: кожен захід додає ще один бар'єр для потенційних атакуючих, роблячи ваш застосунок значно важчим для компрометації.

💡 Порада: Якщо ви використовуєте автентифікацію на основі токенів, таких як JWT, ви можете спростити деякі аспекти вашої налаштування безпеки. Однак ніколи не забувайте про важливість правильного налаштування CORS, щоб зберегти контроль над тим, які домени можуть отримувати доступ до вашого API.

Перекладено з: Layered Security in Django: Why ALLOWED_HOSTS, CORS, and CSRF Are Vital

Leave a Reply

Your email address will not be published. Required fields are marked *