Маркер автентичності використовується для запобігання атак на підписи між веб-сайтами (CSRF). Щоб зрозуміти маркер автентичності, спочатку слід зрозуміти атаки CSRF.
КСРР
Припустимо, ви є автором bank.com
. На вашому веб-сайті є форма, яка використовується для переказу грошей на інший рахунок із GET-запитом:
Хакер міг просто надіслати сервер запит HTTP, кажучи GET /transfer?amount=$1000000&account-to=999999
, правда?
Неправильно. Атака хакерів не спрацює. Сервер в основному буде думати?
Так? Хто цей хлопець, намагається ініціювати передачу. Це не власник облікового запису, це точно.
Як сервер це знає? Тому що немає session_id
файлу cookie, що засвідчує запитувач.
Коли ви входите із своїм іменем користувача та паролем, сервер встановлює session_id
файл cookie у вашому браузері. Таким чином, вам не потрібно автентифікувати кожен запит своїм іменем користувача та паролем. Коли ваш браузер надсилає session_id
файли cookie, сервер знає:
О, це Джон Доу. Він зареєструвався успішно 2,5 хвилини тому. Йому добре йти.
Хакер може подумати:
Хм. Звичайний HTTP-запит не працюватиме, але якби я міг отримати руку на цьому session_id
файлі cookie, я був би золотим.
У браузері користувачів встановлено купу файлів cookie для bank.com
домену. Кожен раз, коли користувач робить запит до bank.com
домену, всі файли cookie надсилаються разом. Включаючи session_id
печиво.
Тож якщо хакер може змусити вас зробити заявку GET, яка перераховує гроші на його рахунок, він буде успішним. Як він міг вас обдурити в цьому? Завдяки підробці запиту на веб-сайті.
Насправді це досить просто. Хакер міг просто змусити вас відвідати його веб-сайт. На своєму веб-сайті він може мати такий тег зображення:
<img src="http://bank.com/transfer?amount=$1000000&account-to=999999">
Коли користувач переглядає цей тег зображень, він надсилає GET-запит до цієї URL-адреси. А оскільки запит надходить від його браузера, він надсилає разом із ним усі файли cookie, пов’язані з bank.com
. Якщо користувач нещодавно ввійшов у bank.com
... session_id
cookie буде встановлено, і сервер подумає, що користувач мав намір перерахувати $ 1 000 000 на рахунок 999999!
Ну, просто не відвідуйте небезпечні сайти, і ви будете добре.
Цього недостатньо. Що робити, якщо хтось розмістить це зображення у Facebook і воно з’явиться на вашій стіні? Що робити, якщо він вводиться на сайт, який ви відвідуєте, при нападі XSS?
Це не так вже й погано. Вразливі лише запити GET.
Неправда. Форма, яка надсилає POST-запит, може динамічно генеруватися. Ось приклад з Посібника з безпеки по Rails :
<a href="http://www.harmless.com/" onclick="
var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = 'http://www.example.com/account/destroy';
f.submit();
return false;">To the harmless survey</a>
Маркер автентичності
Коли у вас ApplicationController
це є:
protect_from_forgery with: :exception
Це:
<%= form_tag do %>
Form contents
<% end %>
Складається в це:
<form accept-charset="UTF-8" action="/" method="post">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
Form contents
</form>
Зокрема, створюється таке:
<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
Для захисту від атак CSRF, якщо Rails не бачить маркер автентичності, надісланий разом із запитом, він не вважатиме запит безпечним.
Як нападник повинен знати, що це маркер? Різне значення генерується випадковим чином кожного разу, коли формується форма:
Напад крос-скриптів (XSS) - ось як. Але це різна вразливість для іншого дня.