Доброго времени суток!
Изучаю csrf и не могу понять одну вещь, помогите пожалуйста разобраться.
На сайте learn.javascript есть статья по этому поводу. Там сказано:
Типичный способ защиты сайтов – это «секретный ключ» (secret),
специальное значение, которое генерируется случайным образом и
сохраняется в сессии посетителя. Его знает только сервер, посетителю
мы его даже не будем показывать.
Затем на основе ключа генерируется «токен» (token). Токен делается
так, чтобы с одной стороны он был отличен от ключа, в частности, может
быть много токенов для одного ключа, с другой – чтобы было легко
проверить по токену, сгенерирован ли он на основе данного ключа или
нет.
Для каждого токена нужно дополнительное случайное значение, которое
называют «соль» salt.
Формула вычисления токена:
token = salt + ":" + MD5(salt + ":" + secret) Например:
В сессии хранится secret="abcdef", это значение создаётся один раз.
Для нового токена сгенерируем salt, например пусть salt="1234". token
= "1234" + ":" + MD5("1234" + ":" + "abcdef") = "1234:5ad02792a3285252e524ccadeeda3401". Это значение – с одной
стороны, случайное, с другой – имея такой token, мы можем взять его
первую часть 1234 в качестве salt и, зная secret, проверить по
формуле, верно ли он вычислен.
Не зная secret, невозможно сгенерировать token, который сервер
воспримет как правильный.
Далее, токен добавляется в качестве скрытого поля к каждой форме,
генерируемой на сервере.При её отправке сервер проверит поле csrf,
удостоверится в правильности токена, и лишь после этого отошлёт
сообщение.
«Злая страница» при всём желании не сможет сгенерировать подобную
форму, так как не владеет secret, и токен будет неверным.
Мне непонятно вот что:
secret хранится в сессии, а сессия хранится в куках на клиентской машине, и каждый раз отправляется веб серверу. Разве хакер не сможет получить доступ к кукам? К ним вообще можно же получить доступ? Они хранятся же в файле где-то?
Если токен приходит каждый раз с формой, разве хакер не сможет этот токен из html который пришел выдрать, заюзать его и отправить для своего запроса?
Я так понимаю смысл всей этой ерунды есть только тогда, когда либо
Сайт разрешает кросс-доменные запросы от всех Origin: *
либо
Злоумышленник мог ранее уже встроить форму на тот же сайт через XSS, чтобы оставаться в том же домене, так как во всех остальных случаях у нас есть CORS, зачем нам CSRF?
Не понял, почему формула токена именно такая:
token = "1234" + ":" + MD5("1234" + ":" + "abcdef") = "1234:5ad02792a3285252e524ccadeeda3401"
Зачем нужно соль "1234" склеивать со сгенерированной md5-функцией строкой? Ведь соль 1234 становится явно видна в токене!
Т.е. получается бразузер шлет каждый раз "abcdef" в куках как Id-сесии, и также шлет токен. Сервер еще раз генерирует токен, используя этот id сессии, и сверяет с тем, что пришел от формы? Не совсем ясно, как это помогает, если токен можно подглядеть(если можно?)
Спасибо заранее за помощь!
Отличие от данного вопроса в том, что там так и не понятно, зачем нужен CSRF если есть CORS
Ответ
secret хранится в сессии, а сессия хранится в куках на клиентской машине, и каждый раз отправляется веб серверу. Разве хакер не сможет получить доступ к кукам? К ним вообще можно же получить доступ? Они хранятся же в файле где-то?
Только если у него есть доступ к компьютеру пользователя. Но тогда ему вообще CSRF не нужен, т. к. есть куда более простые способы отправить запрос самому.
Если токен приходит каждый раз с формой, разве хакер не сможет этот токен из html который пришел выдрать, заюзать его и отправить для своего запроса?
Только в случае MITM. При CSRF у хакера нет доступа к серверу, клиенту или каналу связи.
я имею в виду разве он не может получить форму просто еще раз скриптом и этот токен потом отправить в своем запросе?
Не может - тут сработает CORS. Если запрос get, то сервер его получит, но если он не пошлёт разрешающие заголовки, то запрашивающему скрипту браузер ответ не отдаст. А на POST вообще будет OPTIONS-запрос сначала.
А если послать запрос не из браузера, а с сервера, то не будет авторизации пользователя и токен он опять же не получит.
Я так понимаю смысл всей этой ерунды есть только тогда, когда либо
Сайт разрешает кросс-доменные запросы от всех Origin: * либо ...
Нет. Браузер позволит отправит форму, вот:
Не понял, почему формула токена именно такая:
Форма может быть разной.
Зачем нужно соль "1234" склеивать со сгенерированной md5-функцией строкой? Ведь соль 1234 становится явно видна в токене!
Если соли нет, то ключ одного клиента подойдёт другому и хакер сможет использовать свой, поэтому нужна соль.
Хм.. А вообще, что-то я задумался, есть тут сомнения...
Разобрался: даже если хакер встроит свой валидный токен в форму, он не совпадёт с токеном в куках, поэтому форма будет отвергнута как поддельная.
он не совпадет, потому что хакеру неизвестен id сессии, на основе котороой генерируется токен?
Я имел в виду, что у хакера может быть свой токен, который корректен для него. Но этот токен не совпадёт с тем токеном, который лежит у другого пользователя в куках. А из чужих кук он его достать не может.
Т.е. получается бразузер шлет каждый раз "abcdef" в куках как Id-сесии, и также шлет токен. Сервер еще раз генерирует токен, используя этот id сессии, и сверяет с тем, что пришел от формы? Не совсем ясно, как это помогает, если токен можно подглядеть(если можно?)
Сайт не может залезть в чужие куки, поэтому подсмотреть нельзя.
Комментариев нет:
Отправить комментарий