Я намагаюся зрозуміти всю проблему з CSRF та відповідні способи її запобігання. (Ресурси, які я читав, розумію і погоджуюсь з: Ознайомлювальний лист OWASP CSRF , Запитання про КСРР .)
Як я розумію, вразливість навколо CSRF вводиться припущенням, що (з точки зору веб-сервера) дійсне cookie-сеанс у вхідному HTTP-запиті відображає побажання автентифікованого користувача. Але всі файли cookie для початкового домену магічно приєднуються до запиту браузером, тому дійсно весь сервер може зробити висновок про наявність дійсного файлу cookie сеансу у запиті, що запит надходить від браузера, який має аутентифікований сеанс; вона більше не може припускати нічого про кодпрацює в цьому веб-переглядачі, чи відображає це дійсно побажання користувача. Спосіб запобігти цьому - включити в запит додаткову інформацію про аутентифікацію ("маркер CSRF"), яку переносять іншими способами, крім автоматичної обробки файлів cookie браузера. Точно кажучи, файли cookie сеансу аутентифікують користувача / браузера, а маркер CSRF автентифікує код, що працює в браузері.
Отже, у двох словах, якщо ви використовуєте файли cookie сеансу для автентифікації користувачів вашої веб-програми, ви також повинні додати маркер CSRF до кожної відповіді та вимагати відповідного маркера CSRF у кожному запиті, що мутує. Токен CSRF потім робить зворотний перехід від сервера до браузера назад до сервера, доводячи до сервера, що сторінка, що робить запит, затверджується (генерується, навіть) цим сервером.
Що стосується мого запитання, що стосується конкретного способу транспорту, який використовується для цього маркера CSRF на цьому переході.
Здається, звичайно (наприклад, у AngularJS , Django , Rails ) надсилати маркер CSRF з сервера на клієнт у вигляді файлу cookie (тобто у заголовку Set-Cookie), а потім Javascript у клієнта викреслювати його з файлу cookie та приєднувати його як окремий заголовок XSRF-TOKEN для повернення на сервер.
(Альтернативний метод - це той, який рекомендується, наприклад, Express , де маркер CSRF, згенерований сервером, включається в тіло відповіді за допомогою розширення шаблону на стороні сервера, приєднаного безпосередньо до коду / розмітки, що надасть його назад на сервер, наприклад як прихований прийом форми. Цей приклад - це більш зручний для веб-способів ведення справ, але він узагальнить штраф для більш важкого для JS клієнта.)
Чому так часто використовується Set-Cookie як транспорт низхідного потоку для маркера CSRF / чому це гарна ідея? Я думаю, що автори всіх цих рамок уважно розглядали свої варіанти, і не зрозуміли це. Але, на перший погляд, використання файлів cookie для вирішення того, що по суті є обмеженням дизайну файлів cookie, здається непростим. Насправді, якщо ви використовували файли cookie як транспорт у зворотний бік (Set-Cookie: заголовок вниз за потоком для сервера, щоб повідомити браузеру токен CSRF, а Cookie: заголовок вгору для браузера, щоб повернути його на сервер), ви б знову ввели вразливість, яку ви намагаються виправити.
Я розумію, що вищевказані рамки не використовують файли cookie для цілого переходу для маркера CSRF; вони використовують Set-Cookie вниз за потоком, потім щось інше (наприклад, заголовок X-CSRF-Token) вгору за течією, і це повністю усуває вразливість. Але навіть використання Set-Cookie в якості транспорту нижче за течією потенційно вводить в оману та небезпечно; тепер браузер приєднає маркер CSRF до кожного запиту, включаючи справжні шкідливі запити XSRF; в кращому випадку, що робить запит більшим, ніж потрібно, а в гіршому - якийсь добронамерений, але неправильно керований фрагмент коду сервера може насправді спробувати його використати, що було б дуже погано. Крім того, оскільки фактичним призначеним одержувачем маркера CSRF є клієнтський Javascript, це означає, що цей файл cookie не може бути захищений лише http-адресою.