---
title: CSRF
---
<div class="header__logo" >CSRF или как заставить жертву то, чего она не хочет!</div>
<p>
</p>
<style>
.header__logo {
font-size: 30px;
font-weight: 700;
color: #270469;
text-align: center;
}
</style>
<style>
.secret{
display: flex;
margin-left: auto;
margin-right: auto;
width: 50%;
}
</style>
<style>
.secret__block{
background-color: #fff;
display: block;
max-width: 100%;
height: auto;
transition: opacity .8s linear;
color: black;
text-transform: uppercase;
font-weight: 700;
text-align: center;
}
</style>
<style>
.secret__block img{
opacity: 5;
}
</style>
<style>
.secret__block:hover {
opacity: 2 ;
}
</style>
<style>
.secret__img {
opacity: ;
transition: transform 1.8s linear;
}
</style>
<style>
.secret__img img{
opacity: 0 ;
transition: transform 1.8s linear;
}
</style>
<style>
.secret__img img: hover{
opacity: 5 ;
transition: transform 1.8s linear;
}
</style>
<style>
.secret__img img {
display: block;
max-width: 100%;
height: auto;
transition: opacity 1.8s linear;
}
</style>
<style>
.secret__img:hover {
opacity: 5 ;
}
</style>
<style>
.secret__inner {
position: relative;
background-color: #fff;
}
</style>
<style>
.secret__inner:hover .secret__img {
transform: translate3d(-10px, -10px, 0);
}
</style>
<style>
.secret__inner img:hover {
opacity: 0;
transition: opacity 2s linear;
}
</style>
<style>
.secret__inner img {
transition: opacity 2s linear;
}
</style>
<style>
.secret__inner:hover .secret__img img {
opacity: 1;
}
</style>

<div class="TOC" >
Содержание:
<p>
</p>
</div>
<style>
.TOC {
font-size: 26px;
font-weight: 550;
color: #270469;
text-align: left;
</style>
> [TOC]
---
# CSRF - что за зверь и чем опасен?
:::info
Возьму самое первое определение, а именно из википедии, так как оно отлично описывает смысл CSRF:
**CSRF** (англ. cross-site request forgery — «межсайтовая подделка запроса») — вид атак на посетителей веб-сайтов, использующий недостатки протокола HTTP и браузеров. Жертва заходит на сайт злоумышленника, и от её лица тайно отправляется запрос на другой сервер (например, на сервер платёжной системы). Этот запрос осуществляет некую вредоносную операцию (например, перевод денег на счёт злоумышленника). Для осуществления данной атаки жертва должна быть аутентифицирована на том сервере, на который отправляется запрос, и этот запрос не должен требовать какого-либо подтверждения со стороны пользователя, которое не может быть проигнорировано или подделано атакующим скриптом.
:::
Если упростить вышесказанное, то получится следующее:
CSRF - вид атаки, с помощью которой можно от лица жертвы выполнять различные вредоносные действия на уязвимом веб-сайте:
1) Поменять email от аккаунта жертвы на свой
2) Перевести деньги себе на счёт
3) Удалить аккаунт жертвы и тд.
Давайте чуть детальнее разберёмся с тем, по какой схеме работает данная атака!
---
# Разбор схемы атаки, и что нужно, чтобы эту атаку совершить

Обычно схема атаки выглядит следующим образом:
1) Злоумышленник отправляет жертве ссылку на подконтрольный сайт через почтовую рассылку, социальные сети и тд. Допустим с темой "ХАЛЯВНЫЕ ШПАРГАЛКИ ДЛЯ СДАЧИ ЭКЗАМЕНОВ ВО МТУСИ ПО ССЫЛКЕ НИЖЕ!!!"
2) Ничего не подозревающая жертва, которая ~~решила забить болт на экзамены~~ не успела подготовиться к экзаменам, переходит по ссылке, чтобы сдать все экзамены и не потерять свою стипендию.
3) Попадая на сайт браузер жертвы выполняет вредоносный код, который находится на сайте злоумышленника.
4) Браузер жертвы отправляет нехороший запрос(допустим на смену почты от аккаунта жертвы на почту злоумышленника) на уязвимый веб-сайт, включая также учетные данные пользователя(cookie, по которым можно определить что за пользователь отправил запрос, и нужно ли его выполнять).
5) Уязвимый веб-сайт обрабатывает запрос, видит по кукам, что это пользователь... ну допустим, Вася Пупкин, и меняет почту от аккаунта Васи Пупкина на почту злоумышленника.
6) Злоумышленник восстанавливает пароль от аккаунта и использует его так, как хочет >:)
Вообщем-то как-то так:)
**А что нужно, чтобы можно было совершить CSRF-атаку?**
Чтобы CSRF-атака была возможной, должны быть соблюдены три ключевых условия:
1) <b>Актуальное действие</b>. В приложении есть действие, которое у злоумышленника есть причина вызвать. Это может быть привилегированное действие (например, изменение разрешений для других пользователей) или любое действие с данными пользователя (например, изменение собственного пароля пользователя). Думаю тут вопросов нет:)
2) <b>Обработка сеансов на основе cookie</b>. Выполнение действия включает в себя отправку одного или нескольких HTTP-запросов, и приложение полагается исключительно на файлы cookie сеанса для идентификации пользователя, отправившего запросы. Другого механизма для отслеживания сеансов или проверки пользовательских запросов не существует. Это спорный момент, так как CSRF также возникает в других контекстах, когда приложение автоматически добавляет некоторые учетные данные пользователя в запросы, такие как базовая аутентификация HTTP и аутентификация на основе сертификатов. Так что главное, чтобы сеансы как бы сами подставлялись за нас браузером жертвы или иным способом, главное чтобы мы сами не были вынуждены этим заниматься.
3) <b>Нет непредсказуемых параметров запроса</b>. Запросы, выполняющие действие, не содержат параметров, значения которых злоумышленник не может определить или угадать. Например, когда злоумышленник патается заставить браузер жертвы изменить пароль от аккаунта жертвы, функция не уязвима, если злоумышленнику необходимо знать значение существующего пароля. Или если чуть забежать, в запросе нет CSRF токена со значением, которое нельзя предугадать, вообщем нет параметров с "непонятками".
Например, предположим, что приложение содержит функцию, которая позволяет пользователю изменить адрес электронной почты в своей учетной записи. Когда пользователь выполняет это действие, он делает HTTP-запрос, подобный следующему:
```
POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Cookie: session=someSession
email=vasya.pupkin@mail.ru
```
Это соответствует условиям, необходимым для CSRF:
1) Действие по изменению адреса электронной почты в учетной записи пользователя представляет интерес для злоумышленника. После этого действия злоумышленник, как правило, сможет инициировать сброс пароля и получить полный контроль над учетной записью пользователя.
2) Приложение использует cookie, чтобы определить, какой пользователь выдал запрос. Других токенов или механизмов для отслеживания сеансов пользователей не существует.
3) Злоумышленник может легко определить значения параметров запроса, необходимые для выполнения действия. А если проще, то всё, что нам нужно, это просто указать новую почту.
С учетом этих условий злоумышленник может создать веб-страницу, содержащую следующий HTML-код:
```
<html>
<body>
<form action="https://vulnerable-website.com/email/change" method="POST">
<input type="hidden" name="email" value="evil.hacker@hacked.net" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
```
Если пользователь-жертва посещает веб-страницу злоумышленника, происходит следующее:
1) Страница злоумышленника инициирует HTTP-запрос к уязвимому веб-сайту.
2) Если пользователь авторизовался на уязвимом веб-сайте, его браузер автоматически включит cookie в запрос (при условии , что cookie SameSite не используются).
3) Уязвимый веб-сайт обработает запрос обычным образом, расценит его как сделанный пользователем-жертвой и изменит его адрес электронной почты.
Знаю-знаю, очень много текста, сейчас перейдём к практике, только разберёмся с тем, а какие инструменты можно использовать.
---
# Какие инструменты лучше использовать, для экономии времени?
1. [XSRFProbe](https://github.com/0xInfection/XSRFProbe)
2. Burp suite
3. [OWASP ZAP](https://resources.infosecinstitute.com/topic/csrf-proof-of-concept-with-owasp-zap/)
На Burp Suite нет ссылки, так как я в этом топике сам расскажу, как можно использовать Burp suite для эксплуатации CSRF-атаки. И для этого мне понадобиться в том числе функция, о которой я говорил в [своей лекции по Burp Suite](https://hackmd.io/@l2DM7TZmTWmviRggKdE_zA/HJ4ilcp4i#Engagement-tools) - **Generate CSRF PoC**.
Ну чтож, а теперь давайте перейдём к примеру эксплуатации!
---
# Пример эксплуатации (POST-запрос)
:::warning
**Лабораторная**:
https://portswigger.net/web-security/csrf/lab-no-defenses
:::
В качестве примера я возьму самую первую лабораторную из portswigger'а, и на ней покажу как можно использовать CSRF.
1. Переходим к лабораторной, видим, что нам нужно изменить email от аккаунта жертвы на свой с помощью CSRF. Также нам дают креды от пользователя peter wiener, которые нам пригодятся. Ну чтож, кликаем "Access the lab" и поехали!

2. Далее мы попадаем на сайт, в котором есть различные посты. Мы можем просматривать их, комментировать и тд. Но это всё нам неинтересно. Также сверху есть кнопочка "Go to exploit server", о которой позже
---

---

---

---

---
3) Намного интеснее для нас кнопка "Мой аккаунт", давайте нажмём на неё и войдём в свой аккаунт.

---

---

4) Войдя в аккаунт мы сразу видим подозрительную функцию: смена email'a от аккаунта. Давайте поменяем его и посмотрим в истории Burp Suite, какие запросы летали:


5) Такс, мы видим интересный POST-запрос по маршруту /my-account/change-email. Тут и куки есть, и параметр, который мы можем контролировать - ИДЕАЛЬНЫЙ ПРЕТЕНДЕНТ ДЛЯ CSRF!
```
POST /my-account/change-email HTTP/1.1
Host: 0a3800c203c090cfc20a254500ae004e.web-security-academy.net
Cookie: session=oB09gteNY3eJQ11tvNfkDPkdD814o5TJ <- Используются куки для аутентификации
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 23
Origin: https://0a3800c203c090cfc20a254500ae004e.web-security-academy.net
Referer: https://0a3800c203c090cfc20a254500ae004e.web-security-academy.net/my-account
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close
email=arroiz%40mtuci.ru <- Параметр, который мы можем контролировать
```
6) Теперь нам надо сделать вредоносный код из всего этого. Можно конечно взять шаблон или писать руками.. Но мы с вами умные, и знаем про Generate CSRF PoC. Так что давайте его и используем! Кликаем ПКМ по запросу в Burp Suite и выбираем Generate CSRF PoC.

7) Далее у нас открывается окно, состоящее из следующих элементов:

7.1) Наш POST-запрос, по которому мы и хотим сделать вредоносный код
7.2) Инспектор, о котором рассказывалось в [лекции по Burp Suite](https://hackmd.io/@l2DM7TZmTWmviRggKdE_zA/HJ4ilcp4i#Inspector)
7.3) Сгенерированный по запросу вредоносный код
7.4) Можно заново сгенерировать код, об этом позже
7.5) Кнопка для тестирования CSRF в браузере, после её нажатия сгенерируется ссылка, по которой если перейти, то сработает CSRF-атака
7.6) Скопировать HTML
7.7) Закрыть окно Generate CSRF PoC
7.8) Поиск какой-либо строчке в HTML или в POST-запросе
и вс...
А нет, есть ещё 1 важная кнопка:

НАСТРОЙКИ, куда же без них! Тут можно выбрать техники CSRF, и, самое важное, добавить в HTML скрипт, который будет выполнять CSRF-атаку автоматически, как только жертва попадёт на сайт, где будет содержаться данный код. Так что кликаем на эту галочку и заново генерируем код, чтобы скрипт появился:


А теперь давайте разберёмся, а что это за HTML-код тут написан:

Если по простому, то тут написана HTML'ка, в которой есть форма, если эту форму заполнить(в нашем случае есть скрытый input с именем email, в который уже заранее забит тот email, что я писал ранее: ```value="arroiz@mtuci.ru"```) и нажать кнопку submit(или если скрипт сам нажмёт как бы эту кнопку >:) ), то отправится POST-запрос на ```https://0a3800c203c090cfc20a254500ae004e.web-security-academy.net/my-account/change-email``` с параметром email, значение которого будет ```arroiz@mtuci.ru```. Собственно так выглядит тот самый ***вредоносный*** код, который подвяжет аккаунт жертвы под нашу почту.
А что делать дальше?
8) Вспоминаем про кнопку `"Go to exploit server"`. Давайте нажмём на неё!

9) Нажав на неё мы попадаем как бы на подконтрольный нами сервер:)
Тут мы можем создавать ответы сервера: редактировать заголовки ответа, изменять тело ответа, выбирать протокол и тд. Также ниже мы видим 4 кнопки: Store(который применяет наши настройки, если мы что-то поменяли), View exploit(показывает нам страницу с эксплойтом, которую мы сделали), Deliver exploit to victim(это кнопка за нас отправляет ссылку на сайт с вредоносным кодом жертве, причём эта жертва всегда переходит, и нам не нужно тратить своё время на её уговаривание:) ), и кнопка Access log(показывает логи сервера).
Теперь вы знаете зачем он нужен, а то я в первый раз растерялся, когда увидел `"Go to exploit server"` и не смог решить лабу :D
Ну ладно, обратно возвращаемся к лабе!
10) Копируем наш **вредоносный** HTML-код, вставляем его в тело ответа сервера и применяем изменения:


11) Теперь просто отправляем ссылку на наш сайт с вредоносным кодом жертве:

А теперь я быстренько резюмирую, что мы сейчас сделали:
1) Мы нашли функциональность на сайте, которая может быть интересна злоумышленнику, а именно смена email'a.
2) Потом мы проанализировали POST-запрос на маршрут ```/my-account/change-email```, и поняли, что этот запрос идеален для создания CSRF-атаки.
3) Мы использовали Generate CSRF PoC, чтобы создать вредоносный HTML-код по нашему POST-запросу.
4) Мы перешли на наш сервер и в качестве тела ответа сервера поставили вредоносный HTML-код.
5) Применили изменения и отправили ссылку на наш сайт с вредоносным HTML-кодом жертве.
6) Жертва перешла по ссылке и попала наш сайт, где валяется злой код.
7) Наша страница инициировала HTTP POST-запрос на страницу ```https://0a3800c203c090cfc20a254500ae004e.web-security-academy.net/my-account/change-email```, с параметром ```email=arroiz@mtuci.ru```.
8) Авторизированный на уязвимом веб-сайте браузер жертвы автоматически включает cookie в запрос.
9) Уязвимый веб-сайт обработал запрос обычным образом, и изменил email от аккаунта жертвы на arroiz@mtuci.ru.
Ну чтож, надеюсь тут всё понятно. Для большей ясности советую перечитать этот раздел заново и выполнить лабораторную самостоятельно, чтобы вы могли сами всё потыкать=)
И прошу обратить ванимание на то, что этот раздел называется "Пример эксплуатации **(POST-запрос)**". Я думаю вы уже догадались, что тут написано POST-запрос, так как мы сделали CSRF-атаку в POST-запросе, но если вы ещё не поняли, то давайте ещё раз взглянем на наш HTML-код:

Данный код инициирует **POST** запрос на уязвимый сайт по маршруту /my-account/change-email. Вообще выбор запроса зависит от того, какой запрос используется для той или иной функции. Допустим функция смены email'a доступна не только по POST-запросу, что если она разрешает и GET-запросы? Как же нам тогда использовать CSRF?
---
# Пример эксплуатации (GET-запрос)
Некоторые простые эксплойты CSRF используют метод GET и могут быть полностью автономными с одним URL-адресом на уязвимом веб-сайте. В этой ситуации злоумышленнику может не понадобиться использовать внешний сайт(тот самый Exploit server), и он может напрямую передать жертве вредоносный URL-адрес. В предыдущем примере, если запрос на изменение адреса электронной почты можно выполнить с помощью метода GET, то по сути мы можем просто передать следующую ссылку жертве:
```
https://vulnerable-website.com/my-account/change-email?email=arroiz@mtuci.ru
```
Если жертва перейдёт по этой ссылке, то у аккаунта изменится email на arroiz@mtuci.ru. Мы также можем использовать CSRF-атаку в GET-запросах и с помощью внешнего сервера, как было в лабораторной выше. И у нас тут даже 2 варианта использования:)
1) Используем опять Generate CSRF PoC, и сгенерированный код со скриптом автообработки просто кидаем в тело ответа нашего внешнего сервера (причём, обратите внимание, тот уже нет строчки method="POST", так как это уже GET-запрос !!!) :
```
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://0a9d00db04bd6370c1bb036e007400c2.web-security-academy.net/my-account/change-email">
<input type="hidden" name="email" value="arroiz@mtuci.ru" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
```
2) Вместо огромного HTML-кода мы можем использовать лаконичный тег ``<img>``, и в качестве значения атрибута src указываем URL, после загрузки которого произойдёт смена почты у аккаунта.
```
<img src="https://vulnerable-website.com/my-account/change-email?email=arroiz@mtuci.ru">
```
---
# Способы защиты от CSRF
Как вы понимаете, это были самые простые примеры использования, которые были актуальны несколько лет назад:)
На данный момент уже были придуманы определённые механизмы защиты от простого использования CSRF, и давайте я вам о них расскажу!
## Защита от CSRF с помощью CSRF-token'a
:::info
**Токен CSRF** — это уникальное, секретное, непредсказуемое значение, которое генерируется приложением на стороне сервера и передается клиенту таким образом, что оно включается в последующий HTTP-запрос, сделанный клиентом. Когда делается более поздний запрос, приложение на стороне сервера проверяет, включает ли запрос ожидаемый токен, и отклоняет запрос, если токен отсутствует или недействителен.
Токены CSRF могут предотвратить атаки CSRF, лишив злоумышленника возможности создать полностью действительный HTTP-запрос, подходящий для передачи пользователю-жертве. Поскольку злоумышленник не может определить или предсказать значение токена CSRF пользователя, он не может создать запрос со всеми параметрами, которые необходимы приложению для выполнения запроса.
:::
По вышесказанному можно понять, что CSRF-токен - случайный набор байт, который генерируется на сервере и который привязан к сессии пользователя. Токен служит для того, чтобы рушилось 3ье ключевое условие CSRF-атаки - "Нет непредсказуемых параметров запроса". Из-за того, что появляется обязательный параметр в запросе, значение которого злоумышленник не может предугадать, этот самый злоумышленник не может провернуть CSRF-атаку на жертве. Вот и весь смысл данного токена:)
Выглядит он примерно так в запросе(посмотрите в самый низ):
```
POST /my-account/change-email HTTP/1.1
Host: 0a9d00db04bd6370c1bb036e007400c2.web-security-academy.net
Cookie: session=ASSuq1TOUtDTkHn2hqR4LDcFoHAiqSsH
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 61
Origin: https://0a9d00db04bd6370c1bb036e007400c2.web-security-academy.net
Referer: https://0a9d00db04bd6370c1bb036e007400c2.web-security-academy.net/my-account
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close
email=arroiz%40mtuci.ru&csrf=W72nQxthEn2lPcePwPfbubvToHQoh9Zi <- вот и токен)
```
Соответственно, когда вы будете генерировать CSRF-POC по этому запросу, у вас там появится csrf-токен, и с ним уже будут проблемы:)
Если вам интересно узнать побольше от том, как генерироват токен, и как передавать его пользователю, то вот [ссылка на мини-статью portswigger'a об этом](https://portswigger.net/web-security/csrf/preventing).
## Защита от CSRF с помощью SameSite cookie
Некоторые веб-сайты защищаются от CSRF-атак с помощью SameSite cookie.
:::info
**SameSite** — это механизм безопасности браузера, который определяет, когда cookie веб-сайта включаются в запросы, исходящие с других веб-сайтов. Ограничения cookie SameSite обеспечивают частичную защиту от различных межсайтовых атак, включая CSRF, межсайтовые утечки и некоторые эксплойты CORS .
:::
SameSite позволяет браузерам и владельцам веб-сайтов ограничивать, какие межсайтовые запросы, если таковые имеются, должны включать определенные cookie. До того, как был введен механизм SameSite, браузеры отправляли cookie при каждом запросе к домену, который их выдал, даже если запрос был инициирован не связанным сторонним веб-сайтом. Ну собственно как в первой лабораторной:)
Все основные браузеры в настоящее время поддерживают следующие уровни ограничений SameSite:
```Set-Cookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=Strict;```
```Set-Cookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=Lax;```
```Set-Cookie: SessionId=sYMnfCUrAlmqVVZn9dqevxyFpKZt30NN; SameSite=None;```
**Если cookie установлен с SameSite=Strict** атрибутом, браузеры не будут отправлять его ни в каких межсайтовых запросах. Проще говоря, это означает, что если целевой сайт для запроса не совпадает с сайтом, отображаемым в настоящее время в адресной строке браузера, он не будет включать cookie.
**Если для SameSite атрибута установлено значение Lax**, браузер будет включать cookie в запросы, исходящие с другого сайта, но только при соблюдении двух условий:
1) Запрос использует метод GET. Запросы с другими методами, такими как POST, не будут включать cookie.
2) Запрос возник в результате навигации пользователя на верхнем уровне, например при нажатии на ссылку. Другие запросы, например инициированные сценариями, не будут включать cookie. Проще говоря, если пользователь сам нажал на кнопку submit в Generate CSRF-PoC, то всё сработает, но если запрос к уязвимому сайту будет инициирован автоматически сайтом злоумышленника, без подтверждения со стороны пользователя, то cookie не будут включены в запрос.
:::warning
Lax - ограничение по умолчанию, применяемое Chrome в тех случаях, когда SameSite атрибут не указан явно при настройке cookie. Поскольку это предлагаемый новый стандарт!
:::
Использование SameSite cookie в Lax режиме тогда обеспечивает частичную защиту от CSRF-атак, поскольку действия пользователя, являющиеся целями CSRF-атак, часто реализуются с использованием метода POST, а не GET. Однако всё равно есть несколько интересных вещей, связанных с GET-запросом:
1) Некоторые приложения реализуют конфиденциальные действия с использованием запросов GET(та же смена почты у аккаунта).
2) Многие приложения и платформы терпимы к различным методам HTTP. В этой ситуации, даже если само приложение по своей конструкции использует метод POST, оно фактически будет принимать запросы, переключенные на использование метода GET. То есть можно использовать как POST, так и GET.
**Если cookie установлен с SameSite=None** атрибутом, это полностью отключает ограничения SameSite, независимо от браузера. В результате браузеры будут отправлять этот файл cookie во всех запросах к сайту, который его выдал, даже в тех, которые были инициированы совершенно не связанными сторонними сайтами.
Поэтому SameSite cookie редко используют без csrf-токена, они плохо обеспичивают защиту от csrf-атак, либо делают жизнь пользователя сложнее. Однако если использовать и SameSite cookie, и csrf-токен, злоумышленнику придётся туго!
## Защита от CSRF на основе Referer
:::info
Заголовок HTTP Referer — это необязательный заголовок запроса, который содержит URL-адрес веб-страницы, связанной с запрашиваемым ресурсом. Как правило, он автоматически добавляется браузерами, когда пользователь запускает HTTP-запрос, в том числе щелкая ссылку или отправляя форму. Существуют различные методы, которые позволяют странице ссылки скрывать или изменять значение заголовка Referer. Часто это делается из соображений конфиденциальности.
:::
Некоторые приложения используют HTTP-заголовок Referer, чтобы попытаться защититься от атак CSRF, обычно путем проверки того, что запрос исходит из собственного домена приложения. Этот подход, как правило, менее эффективен и часто подлежит обходным путям. Об этом ниже:)
Как обычно выглядит данный заголовок и его значение:
``` Referer: https://0a9d00db04bd6370c1bb036e007400c2.web-security-academy.net/my-account ```
---
# Способы обхода защиты от CSRF
Как вы понимаете, не всём в этом мире идеально, и даже такую, на первый взгляд, хорошую защиту можно обойти:)
И сейчас я вам расскажу про несколько таких случаев!
**Но мини предупреждение!** Я не буду разбирать много разных лаб и тд. Я просто пройдусь по 1 лабороторной в каждом разделе и опишу 1 пример обхода защиты, остальные методы вы можете и должны изучить сами, хоть на том же [portswigger'e](https://portswigger.net/web-security/csrf), так как вам надо самим научиться **УЧИТЬСЯ** и **ПРАКТИКОВАТЬСЯ**!
## Пример обхода защиты, построенной на CSRF-токене (проверка токена CSRF зависит от метода запроса)
:::warning
**Лабораторная**:
https://portswigger.net/web-security/csrf/bypassing-token-validation/lab-token-validation-depends-on-request-method
:::
Возьмём тот же сайт, что был описан [ранее](https://hackmd.io/jDwEgns_Qzyj2P2BNhC8WA?both#Пример-эксплуатации-POST-запрос). Функционал и страничка та же, однако есть различие: есть CSRF-токен! Вот пример HTTP-запроса, где он появляется во всей красе:
```
POST /my-account/change-email HTTP/1.1
Host: 0a2c005a04988705c3f4ec220098001e.web-security-academy.net
Cookie: session=798TmRbJY4uEwkH7uUwNsvu8TavRzDKn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 61
Origin: https://0a2c005a04988705c3f4ec220098001e.web-security-academy.net
Referer: https://0a2c005a04988705c3f4ec220098001e.web-security-academy.net/my-account
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close
email=arroiz%40mtuci.ru&csrf=79sBpdF3UYJfiJZ0gbfIlQ5cTruhTsTu <- А вот и токен
```
Изменить или предугадать токен нельзя, как и удалить. Однако если изменить данный POST-запрос на GET, то токен можно удалить и дальше спокойно провернуть обычную CSRF-атаку в GET-запросе:







После отправки ссылки жертве на наш сервер с вредоносным кодом, произойдёт смена email'a от аккаунта жертвы на нашу!
:::danger
**А с чем связана данная уязвимость?**
Функция по смене почты доступна как по GET-запросу, так и по POST. Но тут 1 разница: в POST-запросе сделали так, что **должен быть действительный** csrf-токен, так как он там потом обрабатывается, сравнивается и тд. А GET-запрос может не иметь csrf-токена, так как с ним нет никаких манипуляций далее. Вообщем либо просто недоглядели, либо понадеялись, что никто не будет проверять доступность данной функции по GET-запросу:)
:::
Другие лабораторные на обход CSRF-токена вы можете найти [ТУТ](https://portswigger.net/web-security/csrf/bypassing-token-validation)!
## Пример обхода защиты, построенной на SameSite cookie (Обход SameSite Lax с помощью переопределения метода)
:::info
Во время написания данного топика (04.01.2023) Portswigger academy изменил структуру 12ого раздела - CSRF. Там слегка изменили порядок топиков, и, самое главное, добавили лабораторные, связанные с обходом SameSite cookie. И в этом не было бы ничего такого, если бы они не были связаны с другими темами, которые мы пока не проходили на кружке. Кроме того, даже если следовать плану самого портсвиггера, другие темы проходятся позже, например, сама по себе CSRF это 12 тема, 2ая лабораторная из раздела "Bypassing SameSite cookie restrictions" имеет в себе тему из 15 раздела. 3ья лабораторная имеет тему из 11 и 16, а 4ая касается темы из 22 раздела.
Поэтому, если вы идёте строго по плану Portswigger'a, или вы пока не знаете такие темы как "OAuth 2.0 authentication vulnerabilities" и "Testing for WebSockets security vulnerabilities", я вам рекомендую решить только 1ую лабораторную из раздела "Bypassing SameSite cookie restrictions". Собственно, именно её я вам и опишу.
:::
:::warning
**Лабораторная**:
https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions/lab-samesite-lax-bypass-via-method-override
:::
**Функциональность и тд, как всегда, нам опять нужно сменить почту от аккаунта жертвы.**
В данной лабораторной используется SameSite Lax, а значит cookie будут включаться только при 2ух условиях:
1) Запрос использует метод GET. Запросы с другими методами, такими как POST, не будут включать cookie.
2) Запрос возник в результате навигации пользователя на верхнем уровне, например при нажатии на ссылку. Другие запросы, например инициированные сценариями, не будут включать cookie. Проще говоря, если пользователь сам нажал на кнопку submit в Generate CSRF-PoC, то всё сработает, но если запрос к уязвимому сайту будет инициирован автоматически сайтом злоумышленника, без подтверждения со стороны пользователя, то cookie не будут включены в запрос.
В данной лабораторной делается акцент именно на 1ом условии. Нам нужно, чтобы мы могли использовать GET-запрос. Давайте посмотрим, а можем ли мы его вообще использовать:)
Проверяю, что с POST-запросом могу поменять у себя почту:

Код 302, отлично, значит могу, а что если я поменяю запрос на GET:


**Код 405, метод не разрешён...** А что тогда делать:)?
А тут всё просто!
:::info
Даже если обычный **GET** запрос не разрешен(собственно как в нашей ситуации :) ), некоторые платформы предоставляют способы переопределения метода, указанного в строке запроса. Например, Symfony поддерживает параметр _method в формах, который имеет приоритет над обычным методом маршрутизации.
Грубо говоря, мы можем послать GET-запрос, который потом переопределиться в Symfony в POST, таким образом мы впринципе сможем изменить почту нашим запросом(так как он не будет теперь считаться как GET, а будет как POST), а также сможем включить в наш запрос куки жертвы(так как мы первоначально отправляли именно GET-запрос, а значит куки включаться, а то что он внутри переопределился в POST никого не волнует :) )!
:::
В нашу форму мы должны внедрить следующую строчку кода:
```
<input type="hidden" name="_method" value="POST">
```
Здесь и лежит наш параметр _method, также тут есть атрибут value, вот его значение как раз определяет на что сменится первоначальный запрос. Если первоначальный запрос был GET, то внутри он переопределиться в POST.
Ну чтож, давайте тогда переходить к обходу Lax'a:
1) Для удобства я меняю запрос обратно в POST, и от него генерирую Generate CSRF PoC:

2) После 5 строчки нужно добавить тот код, который переопределит метод, и не забудьте вначале добавить скрипт автообработки формы! Иначе вам опять придётся добавлять эту строчку:

3) Добавив скрипт и строчку кода, я выставил в атрибуте method на 5 строчке значение GET, так как мы прежде всего отправляем GET-запрос, чтобы в запрос включались куки. Дальше я выставил в атрибуте value на 6 строчке значение POST, так как мне нужно, чтобы данный GET-запрос переопределился в POST, и функция по смене почты стала доступна. После этих манипуляция я просто копирую данную HTML'ку:

4) Я иду на свой подконтрольный сервер, и в тело ответа вставляю скопированный HTML. После чего применяю изменения и отправляю ссылку на свой сайт жертве:

5) Жертва переходит по ссылке, у её аккаунта изменяется почта, и эта лабораторная выполнена!

:::danger
**А с чем связана данная уязвимость?**
Разработчики забыли ограничить метод переопределения типа запроса в формах, либо просто не знали о его существовании.
:::
Другие лабораторные на обход SameSite cookie вы можете найти [ТУТ](https://portswigger.net/web-security/csrf/bypassing-samesite-restrictions)!
## Пример обхода защиты, построенной на HTTP-заголовке Referer (CSRF, где проверка Referer зависит от наличия заголовка.)
:::warning
**Лабораторная**:
https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses/lab-referer-validation-depends-on-header-being-present
:::
**Функциональность и тд. как в прошлых лабораторных.**
Тут по сути почти такая же история как и с CSRF-токенами:
Некоторые приложения проверяют Referer заголовок, если он присутствует в запросах, но пропускают проверку, если заголовок опущен.
И наша задача состоит в том, чтобы заставить браузер жертвы отбросить данный заголовок, чтобы наш запрос смог обработаться уязвимым сервером. Но давайте просто посмотрим сначала на лабораторную!
1) Берём наш обычный POST-запрос, и проверяем, что всё работает как надо:

2) Код 302, всё работает, а теперь давайте попытаемся изменить значение заголовка Referer:

3) Код 400, неправильное значение заголовка referer. А что это для нас значит? А то, что мы не сможем инициировать смену почты от аккаунта жертвы из нашего сервака, так как у него url совершенно другой! Давайте попытаемся обойти это ограничение, просто удалив данный заголовок:


4) Код 302, отлично! Значит всё, что нам нужно, это заставить браузер жертвы выкинуть данный заголовок из запроса. Это можно сделать если добавить в HTML'ку мета тег, а именно: ```<meta name="referrer" content="never">```. Данный мега-тег заставит браузер выкинуть заголовок referrer из запроса! Так что сейчас мы генерируем PoC от нашего POST-запроса:

5) И вставляем туда данный мета-тег, я его вставлю до тега body. Главное не забудьте добавить скрипт автообработки формы:


6) Дальше просто копируем HTML'ку, вставляем её в тело ответа нашего сервера, применяем изменения и отправляем ссылку на вредоносный сайт жертве:


:::danger
**А с чем связана данная уязвимость?**
Разработчики, конечно, сделали проверку значения заголовка Referer, но забыли проверить, чтобы он впринципе существовал в запросе. Возможно забыли, а возможно просто решили не заморачиваться:)
:::
Другие лабораторные на обход заголовка Referer вы можете найти [ТУТ](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)!
---
# **БОНУС**: использование XSRFProbe на первой лабораторной
:::warning
**Лабораторная**:
https://portswigger.net/web-security/csrf/lab-no-defenses
:::
1) После установки инструмента по инструкции смотрим его help:

2) Отсюда нам понадобиться ключ -u и ключ -c. Первый отвечает за то, какой url сканировать(в нашем случае ```https://0ac500d2043ef03ac08136590027007b.web-security-academy.net/my-account```), второй ключ отвечает за то, какие cookie будет использовать тулза(ей же нужно быть аутентифицированной, чтобы получить доступ к функции по смене пароля, чтобы проверить её). Все это берём из запроса Burp Suite:

3) Вводим все необходимые данные в терминале:

4) Запускаем инструмент и ждём пока он отработает:


5) Нам сразу генерируется готовый POC, который мы можем использовать, только его слегка надо доработать, чтобы он впринципе сработал:

6.1 Добавляем в конце URL'a /change-email, так как всё-таки функци по смене пароля лежит не в /my-account, а в /my-account/change-email
6.2 Добавляем тот email, который вам нужен. Также я добавил скрипт автообработки формы для удобства, и получается что-то типа такого:

7) Вставляем данную HTML'ку в тело ответа сервера, применяем изменения и отправляем ссылку на сайт жертве:


:::warning
**Плюсы инструмента:**
1) Выполняет несколько типов проверок , прежде чем объявить конечную точку уязвимой.
2) Может обнаруживать несколько типов токенов Anti-CSRF в запросах POST.
3) Работает с мощным сканером, который обеспечивает непрерывный обход и сканирование.
4) Стандартная поддержка пользовательских значений файлов cookie и общих заголовков.
5) Точное определение силы токена и анализ с использованием различных алгоритмов.
6) Может генерировать как обычные, так и злонамеренные доказательства концепции CSRF, те самые POC.
7) Хорошо документированный код и максимально обобщенный автоматизированный рабочий процесс .
8) Пользователь контролирует все , что делает сканер.
9) Подробная система логирования ошибок, уязвимостей, токенов и прочего.
10) Неплохая документация.
**Минусы инструмента:**
1) Не всегда понятно в чём кроется проблема, если она появляется.
2) Приходится допиливать POC.
3) На винде запускается слегка через 1 место.
:::
---
# Домашка
Ну чтож, надеюсь, что всё вам было понятно, а если нет, то предлагаю закрепить данный материал!
Домашка состоит из следующих пунктов:
1) Я сознательно не затрагивал разницу между XSS и CSRF, так как на первый взгляд по описанию они очень похожи - оба заставляют браузер жертвы делать то, чего жертва скорее всего не хотела бы:) Так что ваше задание следующее: расписать разницу между XSS и CSRF, причём отдельно выделить самую главную разницу! Я также могу вас спросить какую-то отдельную вещь, если вы забыли её упомянуть или что-то не так поняли.
2) Прорешать все лабораторные, которые были решены в данном топике, все ссылки есть (прислать скриншот где именно высвечивается плашка "Поздравляем, вы решили лабу")!
3) Прорешать отдельно 3-4 лабораторные либо на Portswigger'e, либо на rootme(прислать скриншот где именно высвечивается плашка "Поздравляем, вы решили лабу").
Домашки присылать мне - @ArroizX, в лс!
Срок: до 05.02.2023
А на этом у меня всё, спасибо, что прочитали данный материал!
