Небезопасно ли для клиента javascript устанавливать токен CSRF?

Мне кажется, что основная цель CSRF — подтвердить, что клиент, делающий запрос, является тем клиентом, которого мы ожидаем.

Решение, которое я обычно видел, это:

  1. Сервер генерирует случайный токен CSRF
  2. Сервер устанавливает токен CSRF в файле cookie
    1. Server injects the CSRF token into the form when generating the form OR
    2. Сервер передает токен CSRF в javascript, а javascript вводит токен CSRF в качестве заголовка в XMLHTTPRequests.
  3. Когда запрос получен, он проверяется путем проверки того, что токен CSRF в файле cookie соответствует токену CSRF в значении заголовка/формы.

Для меня очень важно, что сервер генерирует CSRF для (3)(1), но я не могу придумать причину, по которой это необходимо для (3)(2).

Вместо этого, если клиент представляет собой чистый javascript, я считаю, что это безопасно:

  1. Javascript генерирует случайный токен CSRF
  2. Javascript устанавливает токен CSRF в файле cookie
  3. Javascript передает токен CSRF в заголовке при создании XMLHTTPRequest
  4. Сервер проверяет, что токен CSRF в заголовке и файле cookie совпадают.

Насколько я понимаю, 3 и 4 - это то, что злоумышленник не может сделать, поэтому это также будет достаточно блокировать атаки. Это правильно?

Если это безопасно, нужно ли нам вообще выполнять шаги (1) и (2)? Будет ли это также безопасно из-за политики одного и того же происхождения (при условии, что cors настроен правильно)?

  1. Javascript устанавливает заголовок «CSRF-Safe: true» в XMLHTTPRequest
  2. Сервер проверяет, что заголовок CSRF-Safe существует и имеет значение «true».

person Colin    schedule 03.07.2019    source источник
comment
Как вы думаете, почему злоумышленник не может сделать от 1 до 4 и выше? Большинство злоумышленников даже не будут использовать ваш код и создадут запрос в соответствии с уязвимостью, в вашем случае просто установите для заголовка и файла cookie какое-то случайное значение, чтобы обойти проверку.   -  person Lawrence Cherone    schedule 03.07.2019
comment
@LawrenceCherone, но если бы они это сделали, не могли бы они сгенерировать известный код и использовать его для (1) и (2)   -  person ChiefTwoPencils    schedule 03.07.2019
comment
@LawrenceCherone У меня также есть уникальные файлы cookie сеанса для авторизации запроса. Я считаю, что CSRF предназначен только для проверки клиента, когда клиент является браузером. Насколько мне известно, код мобильного приложения не нуждается в проверке CSRF.   -  person Colin    schedule 03.07.2019
comment
@LawrenceCherone, думаю, мой вопрос заставил меня понять, что мы на одной волне. Я только что обратился к вашему неотредактированному комментарию о (1) и (2).   -  person ChiefTwoPencils    schedule 03.07.2019
comment
CSRF предназначен для предотвращения того, чтобы вошедший в систему пользователь выполнял какие-либо действия против своих знаний либо с помощью повтора mitm, либо с помощью кода xss, который прошел.   -  person Lawrence Cherone    schedule 03.07.2019
comment
@LawrenceCherone Я думаю, что XSS и CSRF — это разные классы атак, и я не ожидаю, что токены CSRF предотвратят атаки XSS. en.wikipedia.org/wiki/Cross-site_request_forgery en.wikipedia.org/wiki/Cross-site_scripting — это определенно возможно, хотя сгенерированные сервером токены CSRF также защищают от какой-то класс уязвимостей XSS, о которых я не думаю. Вы знаете какие-нибудь?   -  person Colin    schedule 03.07.2019


Ответы (1)


Да, оба этих упрощенных подхода должны быть безопасными при наличии CORS и политики одного и того же происхождения. На самом деле вам даже не нужен заголовок CSRF-Safe: true, пока вы проверяете тип содержимого.

Википедия подтверждает:

Если данные отправляются в любом другом формате (JSON, XML), стандартным методом является отправка запроса POST с использованием XMLHttpRequest с атаками CSRF, предотвращенными SOP и CORS; существует метод отправки произвольного содержимого из простой HTML-формы с использованием атрибута ENCTYPE; такой поддельный запрос можно отличить от легитимного по типу содержимого text/plain, но если это не применяется на сервере, может быть выполнен CSRF[12][13]

person Russell Davis    schedule 03.07.2019