Як зловмисники змушують користувача виконувати небажані дії та використання CSRF-токенів

Ми вже обговорили основи безпечного Back-End, зокрема, як Java та Spring створюють надійний фундамент. Але безпека системи не обмежується лише серверним кодом. Існує цілий клас атак, які використовують довіру браузера користувача до Вашого сайту, щоб змусити користувача виконувати небажані дії. Цей клас атак називається **CSRF (Cross-Site Request Forgery)**, або **Міжсайтова підробка запитів**.

CSRF часто залишається непоміченою, оскільки зловмисник не краде Ваші паролі чи куки; він просто використовує їхній факт існування. У цій статті ми детально розберемо механізм цієї атаки, чому вона працює, і як CSRF-токени та сучасні заголовки SameSite створюють надійний щит, який миттєво зводить нанівець зусилля зловмисника.

Зміст статті:

  1. Вступ: Аналогія "Підписаний чек" та сутність CSRF
  2. Як працює CSRF: Механізм атаки та автоматична передача кукі
  3. Критичні фактори ризику: Типи запитів і небезпека GET-дій
  4. Приклади та Наслідки Реальних Атак
  5. Захист №1: CSRF-токени — Непередбачуваний Секрет
  6. Захист №2: Заголовки SameSite та Origin
  7. Роль Фреймворків у Захисті (Spring Security)
  8. Висновки та Головні Рекомендації

1. Вступ: Аналогія "Підписаний чек" та сутність CSRF

CSRF: Небажана дія від Вашого імені

Суть CSRF полягає у використанні довіреної автентифікованої сесії користувача на одному сайті (цільовому) для виконання небажаних дій через запит, ініційований на іншому, шкідливому сайті.

Зловмисник не знає Вашого пароля і не може вкрасти Ваші куки сесії. Його мета — змусити Ваш браузер самостійно відправити легітимний запит на Ваш банк або пошту.

Аналогія: Зловмисник, що користується Вашим підписаним чеком ✍️

Уявіть, що Ви зайшли до свого онлайн-банкінгу, авторизувалися, і тепер Ваша сесія активна.

  • Ви (Користувач): Підписали чек (авторизувалися) і залишили його у відкритому блокноті (активна сесія у браузері).
  • Цільовий Сайт (Банк): Довіряє Вашому підпису.
  • Зловмисник (CSRF-код): Створює шкідливу сторінку з прихованою інструкцією: "Переказати 1000 грн на рахунок X".
  • Кур'єр (Браузер): Коли Ви заходите на шкідливу сторінку, браузер, як слухняний кур'єр, автоматично бере Ваш підписаний чек (куки сесії) і відправляє його до Банку разом із шкідливою інструкцією.
  • Банк: Бачить дійсний підпис (куки) і виконує переказ.

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

2. Як працює CSRF: Механізм атаки та автоматична передача кукі

Механізм атаки ґрунтується на двох фундаментальних властивостях вебу:

  1. Браузери автоматично включають куки, пов'язані з доменом, у запити, що надсилаються на цей домен.
  2. Більшість важливих дій (зміна пароля, видалення акаунта) виконуються через передбачувані HTTP-запити.

Етапи атаки

Розглянемо класичну атаку на цільовий сайт bank.com, де дія "переказ коштів" виконується за адресою bank.com/transfer?amount=1000&to=злодій.

  1. Підготовка (Зловмисник): Створює шкідливу сторінку на іншому сайті (evil.com). На цій сторінці він розміщує прихований елемент, наприклад, прихований тег зображення:

    <img src="https://bank.com/transfer?amount=1000&to=злодій" style="display:none;" />

  2. Приманка (Жертва): Жертва, яка щойно авторизувалася на bank.com, відвідує evil.com.
  3. Ініціація (Браузер): Браузер намагається завантажити "зображення" з адреси bank.com.
  4. Автоматична Аутентифікація: Оскільки запит прямує на домен bank.com, браузер автоматично додає до нього усі куки сесії користувача, що належать bank.com.
  5. Виконання (Сервер): Сервер bank.com отримує запит, бачить дійсні куки (підпис), ідентифікує користувача, і, оскільки запит відповідає очікуваному шаблону, виконує переказ коштів, не підозрюючи про підробку.

3. Критичні фактори ризику: Типи запитів і небезпека GET-дій

CSRF-атаки особливо ефективні проти запитів, які легко ініціювати без участі користувача.

Небезпека GET-запитів

У прикладі вище зловмисник використав простий тег <img>. Це можливо, тому що цей запит був GET-запитом.

  • GET-запити можна ініціювати через теги <img>, <a> або &lt;script&gt; без жодної взаємодії з користувачем. Якщо Ваш Back-End виконує критичні дії, як-от "видалити акаунт" (DELETE /user?id=123), через GET-запит, він є надзвичайно вразливим.
  • Рекомендація: Критичні, змінювальні дані дії повинні виконуватися лише через запити, які не можуть бути легко ініційовані, як-от POST, PUT, або DELETE.

POST-запити та їх підробка

Навіть якщо Ви використовуєте правильний POST-запит, зловмисник може створити приховану форму на evil.com, яка автоматично відправляється при завантаженні сторінки (через JavaScript). Це трохи складніше, але цілком можливо.

<form action="https://bank.com/transfer" method="POST">

<input type="hidden" name="amount" value="1000" />

<input type="hidden" name="to" value="злодій" />

</form>

<script>document.forms[0].submit();</script>

4. Приклади та Наслідки Реальних Атак

Наслідки CSRF можуть варіюватися від незначних до катастрофічних:

  • Захоплення акаунта: Зловмисник змушує користувача (наприклад, адміністратора) відправити запит на зміну його електронної пошти або пароля. Якщо зловмисник контролює нову пошту, він отримує повний доступ до облікового запису.
  • Широкомасштабний Спам: На форумах або соціальних мережах атака може змусити користувача опублікувати спам-пост або коментар.
  • Зміна налаштувань: Вразливість може використовуватися для зміни публічних налаштувань користувача (наприклад, зробити приватний профіль публічним).
  • Фінансові Втрати: Найбільш небезпечний сценарій — несанкціонований переказ коштів, як у нашій аналогії з банком.

5. Захист №1: CSRF-токени — Непередбачуваний Секрет 🛡️

CSRF-токен (Token) — це "золотий ключ" для захисту від цієї атаки. Це єдиний надійний і універсальний метод.

Що таке CSRF-токен?

Це унікальний, криптографічно стійкий, непередбачуваний рядок (наприклад, довгий хеш), який генерується сервером для кожної окремої сесії користувача.

Як Токен Ламає Атаку (Принцип "Подвійної Аутентифікації")

Система захисту з токенами вимагає, щоб для виконання критичної дії (наприклад, переказ) користувач надав два докази своєї легітимності:

  1. Куки Сесії: Автоматично надає браузер.
  2. CSRF-Токен: Унікальний секрет, який знає лише легітимний додаток.

Механізм роботи

  1. Генерація: Коли користувач заходить на сторінку, сервер (Back-End) генерує унікальний токен і зберігає його у сесії користувача.
  2. Вбудовування (Front-End): Сервер вставляє цей токен у приховане поле кожної критичної HTML-форми:

    <input type="hidden" name="_csrf_token" value="ABC123XYZ456..." />

  3. Відправлення: Коли користувач натискає "Змінити пароль", його браузер надсилає запит, який містить:

    * А. Куки сесії (автоматично).

    * Б. Значення токена (з прихованого поля).

  4. Валідація (Сервер): Сервер отримує запит і порівнює значення токена з форми (Б) зі значенням, яке він зберіг у сесії (А). Якщо токени збігаються, запит виконується.

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

6. Захист №2: Заголовки SameSite та Origin

Хоча CSRF-токени є головним захистом, сучасні вебстандарти пропонують додаткові шари захисту, які ускладнюють атаку.

Атрибут кукі SameSite (Новий Стандарт)

Це атрибут, який Ви додаєте до своїх кукі сесії. Він контролює, чи слід надсилати куки разом із запитами, що надходять з іншого домену. Сучасні браузери (Chrome, Firefox) за замовчуванням додають цей атрибут до кукі, що значно підвищує безпеку.

  • SameSite=Strict: Куки відправляються лише для запитів, що походять з того ж домену. Це найбезпечніше, але може заважати деяким стороннім посиланням.
  • SameSite=Lax: Куки відправляються лише для навігаційних GET-запитів (коли користувач натискає на посилання), але блокуються для POST-запитів з інших доменів. Це є сучасним золотим стандартом для більшості вебдодатків, оскільки воно забезпечує баланс між безпекою та функціональністю.

Перевірка заголовка Origin (Для API та AJAX)

Для асинхронних запитів (AJAX, які використовуються у Front-End фреймворках, як React) токени часто передаються через спеціальний HTTP-заголовок, а сервер додатково перевіряє заголовок Origin.

  • Заголовок Origin (або Referer) містить інформацію про те, з якого домену надійшов запит. Сервер може перевірити: "Якщо цей запит прийшов не з мого домену (bank.com), я його відхилю".

7. Роль Фреймворків у Захисті (Spring Security)

На щастя, розробникам не потрібно створювати системи захисту від CSRF "з нуля". Сучасні Back-End фреймворки, які ми раніше обговорювали, мають вбудовану, потужну підтримку.

  • Spring Security: Фреймворк Spring Security (для Java) автоматично впроваджує CSRF-захист. За замовчуванням він вимагає наявність токена для всіх POST, PUT, DELETE запитів. Цей захист включається однією конфігурацією.
  • Laravel (PHP): Автоматично генерує токени для кожної сесії та перевіряє їх.

Важливо: Незважаючи на вбудований захист, розробник повинен переконатися, що він не вимкнув його випадково і що токени правильно передаються Front-End частиною додатка (особливо у випадку REST API).

8. Висновки та Головні Рекомендації

CSRF-атака — це не складна технічна уразливість, а радше логічна помилка в довірі між сайтом і браузером. Зловмисник не краде Ваші дані, а просто змушує Вас зробити це за нього.

Щоб захистити свій Back-End і своїх користувачів, дотримуйтесь багаторівневої стратегії захисту:

  1. Обов'язково: Завжди використовуйте CSRF-токени для всіх критичних дій, що змінюють дані (POST, PUT, DELETE).
  2. Стандарт: Встановіть атрибут кукі SameSite=Lax для всіх сесійних кукі.
  3. Гігієна коду: Ніколи не використовуйте GET-запити для дій, що змінюють дані (наприклад, для видалення акаунта).

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