Несоответствие токенов csrf что это
Шпаргалки по безопасности: CSRF
Не смотря на то, что в последнем публиковавшемся перечне уязвимостей OWASP Top 10 2017 CSRF атаки отнесены к разряду “Удалены, но не забыты”, мы решили, что не будет лишним еще раз напомнить о том, как защититься от CSRF атак, опираясь на те же правила, предоставляемые OWASP.
Использование CSRF токена
Использование токена (как stateless, так и statefull методов) является первичным и самым популярным способом защиты. Токен должен быть уникален для каждой пользовательской сессии, сгенерирован криптографически стойким генератором псевдослучайных чисел. OWASP при этом рекомендует для шифрования использовать алгоритм AES256-GCM и SHA256/512 при использовании HMAC.
Существует несколько подходов к работе с токенами: Synchronizer Token, Encryption based Token Pattern, HMAC Based Token
При использовании подхода Synchronizer Token (statefull метод) подразумевается отправка токена при каждом запросе, подразумевающем какие-то изменения на стороне сервера. Если токен не является валидным, то сервер отклоняет запрос.
При отправке запроса на сервер рекомендуется добавлять токен в параметры запроса, нежели в заголовок. Если все же вставляете токен в заголовок запроса, то убедитесь, что он не логируется на сервере. Полученный токен можно сохранять на стороне клиента в скрытом поле:
OWASP рекомендует хранить токен в заголовках, объясняя это тем, что даже если токен раскрыт или у него истек срок действия, то атакующий все равно не сможет подделать запрос, благодаря особенностям работы браузеров.
Также для повышения уровня безопасности предложенного метода, предлагается генерировать случайное имя параметра токена и/или сам токен для каждого запроса. При таком подходе время, в течение которого злоумышленник может воспользоваться украденным токеном, минимально. Однако это может привести к проблемам с юзабилити. Например, нажатие на кнопку “Назад” может привести к отправке на сервер невалидного токена, который содержался на предыдущей странице.
Отправка токена, используя GET запрос, не рекомендуется, так как при таком подходе токен может быть раскрыт: в истории браузера, лог файлах, referrer заголовках.
Encryption based Token
Данный подход является stateless, так как использует шифрование/дешифрование для валидации токена, а значит не требует хранения токена на стороне сервера.
Сервер генерирует токен, состоящий из идентификатора сессии и timestamp (для предотвращения атаки повторного воспроизведения). Для шифрования рекомендуется использовать алгоритм шифрования AES256 в режиме блочного шифрования GSM/GSM-SIV. Использование режима ECB строго не рекомендуется. Зашифрованный сервером токен возвращается клиенту так же, как и в случае с «Synchronizer Token» в скрытом поле формы или же в заголовке/параметре ответа. При получении токена сервер должен расшифровать его, после чего сверить идентификатор сессии, а также сверить timestamp с текущим временем и убедиться, что оно не превышает установленного времени жизни токена.
Если сверка идентификатора сессии проходит успешно, а timesmap – нет, то запрос может считаться валидным. Во всех остальных случаях рекомендуется отклонять запрос и регистрировать его, чтобы в дальнейшем понять как реагировать на подобные запросы.
HMAC Based Token
Также не требует хранения токена, принцип работы похож на Encryption based Token, за исключением того, что вместо шифрования токена используется HMAC (hash-based message authentication code) функция для генерации токена (рекомендуется использовать SHA256 или более сильный алгоритм). При этом токен представляет из себя результат HMAC функции от идентификатора сессии пользователя+ timestamp.
Автоматизация работы с токенами
Главная проблема в противодействии CSRF атакам заключается в том, что разработчики часто просто забывают добавлять функционал обеспечивающий работу с токенами. Чтобы избежать подобных проблем стоит автоматизировать данный процесс:
• напишите обертку, автоматически добавляющую токен к запросам через тег form или при использовании ajax. Например, Spring Security использует подобный подход каждый раз, когда используется тег
• напишите хук, который перехватывает трафик и добавляет токены ко всем уязвимым ресурсам. Так как довольно трудно проанализировать, какой запрос выполняет изменение состояния, нуждаясь в токене, рекомендуется включать токены во все POST ответы, но стоит при этом учитывать затраты на производительность
• автоматически добавлять токен при рендере страницы. Данный подход используется CSRF Guard: токены добавляются ко всем href и src атрибутам, скрытым полям и во все формы
Прежде чем пытаться написать собственную систему автоматической генерации токена, рекомендуется уточнить, имеет ли используемый вами фреймворк возможность по умолчанию обеспечить защиту от CSRF атак. Например, тот же фреймворк Django реализует защиту от CSRF.
Воспользовавшись CSRF в форме входа, злоумышленник может войти в систему,
под видом жертвы. С такой уязвимостью сталкивались такие гиганты как PayPal и Google.
Бороться с CSRF в форме входа можно путем создания пре-сессий, которые создаются до того, как пользователь прошел аутентификацию, и включением токенов в форму входа.
SameSite Cookie – атрибут, описанный в RFC6265bis, цель которого – противодействие CSRF атакам. Работает это следующим образом. Один из способов защиты – проверка заголовков origin и referer, по которым можно понять откуда пришел запрос, но такой подход требует внедрения механизма проверки. Используя атрибут SameSite, мы ограничиваем отправку куки с запросом с посторонних ресурсов. У данного атрибута есть несколько возможных значений: Strict, Lax и None.
Использование значения strict подразумевает, что браузер не будет отправлять куки с любых источников, не совпадающих с доменным именем текущего ресурса.
Значение lax дает возможность не блокировать куки с внешних ресурсов, переход с которых был осуществлен безопасным способом – по протоколу HTTPS. Lax обеспечивает баланс между удобством использования ресурса для пользователей и безопасностью.
Выставить атрибут довольно просто:
На момент написания статьи поддержка атрибута браузерами выглядит вот так:
Важно помнить, что данный атрибут стоит использовать как дополнительную меру защиты, а не как способ обойтись без использования CSRF токена.
Как уже упоминалось выше, один методов защиты – проверка значений referrer и origin заголовка запроса.
Суть данной проверки сводится к проверке значений заголовков на стороне сервера. Если они совпадают с ресурсом, то запрос считается корректным, в противном случае отклоняется. Если заголовок Origin отсутствует, то нужно убедиться, что значение Referrer соответствует текущему ресурсу. OWASP рекомендует отклонять запросы, которые не содержат Origin или Referrer заголовки. Также можно логгировать все подобные запросы, чтобы после проанализировать их и принять решение о том как с ними поступать.
Однако все усложняется, если ваше приложение находится за прокси-сервером, поскольку URL в заголовке при этом будет отличаться. В таком случае есть несколько вариантов:
• сконфигурируйте ваше приложение таким образом, чтобы всегда знать происхождение запроса. Проблема подобного подхода заключается в установке правильного значения, если ваше приложение развернуто на нескольких окружениях (например, dev, QA, production), что приводит проблеме поддержки
• используйте заголовок Host. Данный заголовок даст возможность определять источник запроса независимо от окружения
• используйте заголовок X-Forwarded-Host, цель которого — хранение исходных заголовков, полученных прокси-сервером
Все описанные методы работают только тогда, когда присутствуют заголовки origin и referer. Но встречаются случаи, когда данные заголовки отсутствуют. Вот ряд случаев, когда эти заголовки не включаются в запрос:
• IE 11 не включается заголовок Origin для доверенных сайтов. Остается полагаться только на заголовок Referer
• в случае перенаправления Origin не включен в запрос, так как считается, что он может содержать конфиденциальную информацию, которую не следует отправлять другому источнику
• заголовок Origin включен для всех межсайтовых запросов, но большинство браузеров добавляют его только для POST/DELETE/PUT запросов
Как правило, незначительное количество трафика попадает под описанные категории, но часто не хочется терять даже эту малую часть пользователей, поэтому принято считать валидным запрос со значением null для origin/referrer или со значением, соответствующим списку доверительных доменов.
Double Submit Cookie
Данный подход довольно прост в реализации и не требует хранения токена на стороне сервера (stateless). Суть метода заключается в отправке пользователем токена в параметре запроса и в куках. Каждый запрос, требующий изменения состояния, сверяем значение токена в куках и в запросе. Если сверка идентификатора сессии проходит успешно, а timesmap – нет, то запрос может считаться валидным
Как защитить свой сайт с помощью Anti-CSRF токенов
Токены Anti-CSRF (или просто токены CSRF) — это уникальные значения, используемые в веб-приложениях для предотвращения атак с подделкой межсайтовых запросов (CSRF / XSRF). CSRF-атаки — это атаки на стороне клиента, которые могут использоваться для перенаправления пользователей на вредоносный веб-сайт, кражи конфиденциальной информации или выполнения других действий в рамках сеанса пользователя. В этой статье рассказано, как использовать токены CSRF для защиты пользователей от атак CSRF и их последствий.
Основы Anti-CSRF токенов
Основной принцип, лежащий в основе токенов anti-CSRF (также известных как шаблоны токенов синхронизатора), заключается в том, чтобы предоставить браузеру пользователя уникальную информацию (токен) и проверить, отправляет ли веб-браузер ее обратно. Токен должен быть уникальным и его невозможно угадать третьим лицам. Приложение не должно работать, если оно не проверит эту информацию. Таким образом, только исходный пользователь может отправлять запросы в аутентифицированном сеансе.
Допустим, вы запускаете веб-приложение социальной сети на сайте www.example.com. Чтобы опубликовать сообщение в своем профиле, пользователь заполняет HTML-форму и нажимает кнопку «Отправить».
Это заставляет веб-браузер отправлять POST запрос:
Если пользователь вошел в систему и злоумышленник знает синтаксис этого запроса, злоумышленник может использовать CSRF-атаку для публикации рекламы в профиле пользователя:
В результате веб-браузер отправляет следующий POST запрос:
Если ваш сайт использует простой токен anti-CSRF, веб-сервер устанавливает этот токен в cookie сеанса вашего веб-браузера сразу после входа в систему. Все отправленные формы через скрытое поле (hidden field), будут содержать этот токен. Таким образом это полностью устраняет уязвимость CSRF.
Затем сервер проверит, содержит ли каждый POST запрос требуемый токен:
Если злоумышленник попытается выполнить подделку межсайтового запроса с помощью вредоносного сайта, он не узнает текущий токен, установленный в cookie. Ваш сервер не станет обрабатывать запрос без этого токена, поэтому атака не удастся.
Как генерировать и проверять токены
Когда вы создаете и позже проверяете свой токен, следуйте этим принципам, чтобы убедиться, что ваш anti-CSRF токен не может быть угадан или использован иным образом:
Например, в PHP вы можете сгенерировать токен следующим образом:
И проверьте токен следующим образом:
Anti-CSRF защита для форм
Описанный выше токен анти-CSRF устанавливается при входе в систему в файле cookie сеанса пользователя, а затем проверяется каждой формой. В большинстве случаев этой защиты достаточно. Однако некоторые сайты предпочитают использовать более безопасный подход. Чтобы достичь хорошего компромисса между безопасностью и удобством использования, вы можете создать отдельные токены для каждой формы.
Для этого создайте токен, но не открывайте его напрямую браузеру пользователя. Вместо этого хешируйте токен с именем файла формы, например так:
Когда вы получите запрос, сравните хеши. Если токен действителен и текущая форма действительна, хеши будут совпадать.
Anti-CSRF защита для каждого запроса
Если вам нужен очень высокий уровень защиты, вы можете использовать отдельные токены для каждого запроса. Это просто реализовать: все, что вам нужно сделать, это сделать токен недействительным после его проверки.
У такого подхода есть несколько недостатков для пользователей. Например, пользователи, которым нравится работать с несколькими вкладками, не смогут этого больше сделать. Кнопка возврата также прервет поток. Поэтому, прежде чем рассматривать этот подход, убедитесь, что он не повлияет отрицательно на пользовательский опыт. При создании токенов защиты от CSRF атаках на каждый запрос также учитывайте производительность сервера и используйте менее ресурсоемкие генераторы случайных чисел.
Использование непостоянных токенов
Если ваша веб-страница или веб-приложение очень загружены, а хранилище на сервере ограничено, вы, вероятно, захотите избежать сохранения токенов на стороне сервера. В этих случаях вы можете генерировать и обрабатывать токены криптографически. При таком подходе нет необходимости хранить токен в сеансе сервера:
Обратите внимание, что хотя этот метод поможет вам избежать хранения большого количества информации, но он может иметь накладные расходы на производительность, поскольку криптографические функции потребляют больше ресурсов, чем простая генерация случайных чисел.
Другой вариант для непостоянных токенов — файлы cookie с двойной отправкой. В этом методе сервер устанавливает случайное значение в файле cookie для пользователя еще до его аутентификации. Затем сервер ожидает, что это значение будет отправляться с каждым запросом (например, с использованием значения скрытой формы).
CSRF защита для Ajax
Токены Anti-CSRF также следует использовать для запросов Ajax. Однако перед тем, как реализовать какой-либо тип защиты CSRF для Ajax, убедитесь, что ваш веб-сервер не разрешает междоменные запросы Ajax (проверьте заголовки Cross-Origin Resource Sharing).
В случае Ajax вы можете включить свой токен в скрытое текстовое поле или непосредственно в JavaScript. Затем вы отправляете токен с каждым запросом Ajax и проверяете его присутствие на стороне сервера.
Anti-CSRF токены для формы входа
Принято считать, что Anti-CSRF токены необходимы только тогда, когда пользователь вошел в систему. Поэтому формы входа обычно не используют никакой защиты CSRF. Несмотря на то, что невозможно выдать себя за пользователя до того, как он войдет в систему, отсутствие защиты CSRF для форм входа может привести к тому, что пользователя обманом заставят войти в систему в качестве злоумышленника и раскрыть конфиденциальную информацию. Например, атака может быть проведена следующим образом:
По этим причинам рекомендуется также включать anti-CSRF токены на все страницы входа.
Предотвращение CSRF атак за пределами токенов
Для углубленной защиты от CSRF вы можете комбинировать токены CSRF с другими подходами. Например, вы можете использовать настраиваемые заголовки для проверки запросов Ajax. Этот метод работает, потому что в соответствии с политикой одного источника для добавления заголовков запроса можно использовать только JavaScript из одного источника. Подробное обсуждение этого и других методов предотвращения CSRF см. OWASP Cross-Site Request Forgery Prevention Cheat Sheet.
Токены Anti-CSRF — один из самых безопасных способов защиты от атак CSRF, но в некоторых случаях их можно обойти. Например, если веб-приложение имеет уязвимость межсайтового сценария (XSS), злоумышленник может использовать ее для выполнения сценария, который незаметно извлекает новую версию формы с текущим токеном CSRF. Чтобы предотвратить это и обеспечить надежную безопасность веб-приложений, убедитесь, что вы проверяете свое веб-приложение на все типы уязвимостей, а не только на CSRF.
CSRF-уязвимости все еще актуальны
CSRF (Сross Site Request Forgery) в переводе на русский — это подделка межсайтовых запросов. Михаил Егоров (0ang3el) в своем докладе на Highload++ 2017 рассказал о CSRF-уязвимостях, о том, какие обычно используются механизмы защиты, а также как их все равно можно обойти. А в конце вывел ряд советов о том, как правильно защищаться от CSRF-атак. Под катом расшифровка этого выступления.
О спикере: Михаил Егоров работает в компании Ingram Micro Cloud и занимается Application security. В свободное время Михаил занимается поиском уязвимостей и Bug hunting и выступает на security-конференциях
Дисклаймер: приведенная информация является сугубо мнением автора, все совпадения случайны.
В том, что CSRF-атаки работают виноват этот Cookie-монстр. Дело в том, что многие веб-приложения используют куки (здесь и далее считаем уместным называть cookies по-русски) для управления сессией пользователя. Браузер устроен так, что, если у него есть куки пользователя для данного домена и пути, он их автоматически отправляет вместе с HTTP-запросом.
Cookies
Куки — это небольшой фрагмент данных, который веб-сервер отправляет клиенту в виде name=value в HTTP-заголовке c названием «Set-Cookie». Браузер хранит эти данные на компьютере пользователя, и всякий раз при необходимости пересылает этот фрагмент данных веб-серверу в составе HTTP-запроса в HTTP-заголовке с названием «Cookie».
Куки могут иметь различные атрибуты, такие как: expires, domain, secure, httponly:
Впервые куки появились в браузере Netscape в далеком 1994 году. До сих пор многие веб-приложения используют их для управления сессией пользователя.
Рассмотрим, как работает классическая Сross Site Request Forgery (CSRF) атака.
Допустим, в нашем веб-приложении есть возможность изменять адрес доставки у пользователя, и оно использует куки для управления сессией.
У нас есть HTML-форма, которую пользователь должен заполнить: ввести адрес и нажать кнопку «Сохранить». В результате в бэкенд полетит POST-запрос с HTML-формой. Мы видим, что браузер автоматически поставил туда сессионные куки пользователя. Бэкенд, когда получит такой запрос, посмотрит, что есть такая сессия, это легитимный пользователь, и изменит ему адрес доставки.
Что может сделать атакующий?
Он может на своем сайте attacker.com разместить такую HTML-страничку, которая на самом деле сабмитит HTML-форму на сайт example.com. Так как браузер автоматически вставляет куки пользователя в HTTP-запрос, то бэкенд просто не поймет, является ли данный запрос легитимным — результат ли это заполнения формы пользователем, или это CSRF-атака — и поменяет адрес доставки для пользователя на значение, которое выгодно для атакующего.
Есть другой вариант CSRF-атаки с использованием XHR API. Если о CSRF-атаке с использованием HTML-форм слышали многие, то о данном способе знают меньше, но он тоже работает.
Обратите внимание на атрибут withCredentials, который заставляет браузер автоматически отправлять куки пользователя. Так как значение Content-type равно application/x-www-form-urlencoded, то браузер данный запрос отправит без CORS options preflight request, и опять CSRF-атака будет работать.
Рассмотрим более наглядно, как это происходит.
История CSRF-атак
Вообще о CSRF-атаках известно с 2001 года, когда их начали активно эксплуатировать. В период 2008-2012 такие уязвимости были на каждом первом сайте, в том числе:
Насколько серьезны CSRF-уязвимости?
На самом деле, все зависит от критичности уязвимого действия. Это может быть:
В проекте OWASP Top 10, который содержит 10 наиболее критичных уязвимостей в приложении, в 2010 году CSRF-уязвимости находились на 5 месте. Потом разработчики начали имплементировать различные варианты защиты и уже в 2013 году CSRF-уязвимости сместились на 8 позицию.
В список за 2017 год CSRF-уязвимости вообще не вошли, потому что якобы по статистике сейчас при penetration-тестировании они находятся только в 8% случаев.
Лично я не согласен с данной статистикой, потому что буквально за последние два года находил много CSRF-уязвимостей. Дальше я расскажу, как я это делал.
В классификации Bugcrowd VRT (Vulnerability Rating Taxonomy) Application-wide CSRF-уязвимости имеют рейтинг severity P2 (High). Выше только severity critical, то есть это достаточно серьезные уязвимости.
Рассмотрим, какие варианты защиты от CSRF существуют и как работает каждый из вариантов защиты.
Поэтому, теперь давайте поговорим о 8 способах обхода защиты, которые можно использовать на практике.
Сценарии обхода:
1. XSS (cross-sitescripting)
Если в вашем веб-приложении есть XSS, то это автоматически делает его уязвимым к CSRF, и от этого сложно защититься. Можно только смириться.
2. Dangling markup
Допустим, в нашем приложении есть уязвимость к HTML injection, но нет XSS. Например, есть Content Security Policy (CSP), которая защищает от XSS. Но атакующий все равно может внедрять HTML теги.
Если в нашем приложении реализована защита, основанная на CSRF-токенах, атакующий может внедрить такой HTML, это не закрытые теги image или form:
В результате часть DOM HTML страницы будет отправлена на ресурс атакующего. Высока вероятность того, что если атакующий правильно внедрит такой HTML, тогда то, что придет на сайт атакующего, будет содержать CSRF-токен.
Таким образом узнав токен, атакующий сможет эксплуатировать CSRF классическим способом.
3. Уязвимый субдомен
Допустим, у нас есть субдомен foo.example.com, и он уязвим к subdomain takeover или XSS. В результате subdomain takeover, атакующий полностью контролирует субдомен и может добавлять туда любые HTML-странички или выполнять JS-код в контексте субдомена. Если наш субдомен уязвим к таким вещам, то атакующий сможет обойти следующие типы CSRF-защиты:
Следующий вариант. Допустим, на основном домене, который мы хотим атаковать, есть файл crossdomain.xml. Этот файл используется flash- и PDF-плагинами для субдоменного взаимодействия, и к нему разрешен доступ с любых субдоменов.
Если атакующий может загрузить JS-файл на foo.example.com, то в этом случае он может использовать Service Worker API для субдомена foo.example.com, который на самом деле отдает flash-файл.
Так как у нас есть crossdomain.xml на основном домене, который разрешает взаимодействие субдоменов, то атакующий через этот SWF просто читает CSRF токен.
Кстати, подобная уязвимость недавно была найдена в Amazon, подробнее здесь.
Даже если не сконфигурирован CORS и нет файла crossdomain.xml, но используется защита Double submit cookie, атакующий может просто вставлять куки с субдомена для родительского домена на путь, где он хочет эксплуатировать CSRF, и таким образом обойти Double submit cookie защиту.
4. Bad PDF
Этот сценарий обхода основан на PDF. В Adobe есть PDF плагин, который автоматически устанавливается при установке Adobe Reader. Этот плагин поддерживает так называемый FormCalc скрипт. Правда, сейчас PDF плагин от Adobe работает только в IE11 и Firefox ESR.
В FormCalc есть два замечательных метода: get() и post(). Атакующий с помощью метода get может прочитать CSRF токен, с помощью post отправить к себе на сайт. Так атакующий получает CSRF-токен жертвы.
Допустим, у нас есть возможность загрузить PDF-файл в веб-приложение. На самом деле это может быть даже файл другого формата, например, атакующий может попытаться загрузить PDF под видом картинки, которая является аватаром пользователя.
У приложения есть некоторый API на основном домене, который позволяет получать содержимое загруженного файла. Тогда атакующий может использовать такую HTML страничку, которая с помощью тега embed встраивает PDF-файл, который атакующий загрузил на example.com.
Файл leak.pdf:
Этот файл содержит FormCalc скрипт, который как раз читает страницу Settings.action, где в DOM есть CSRF токен и отправляет с помощью метода post на сайт атакующего.
Дополнительный фокус в том, что для PDF плагина не важно, с каким Content-Type отдается PDF-файл, и даже в HTTP-ответе могут присутствовать другие заголовки (например, Content-Disposition). PDF плагин все равно будет рендерить этот PDF и выполнять FormCalc скрипт.
5. Cookie injection
Если используется Double submit cookie защита, то если атакующий сможет каким-либо образом внедрить куки, то это game over.
Один из наиболее популярных вариантов в этом сценарии — это CRLFinjection.
Если атакующий может вставлять в ответ сервера дополнительные заголовки, то он просто может добавить заголовок Set-Cookie с нужными куками и обойти CSRF-защиту.
Другой вариант связан с особенностями обработки куков браузером.
Например, в Safari можно через запятую вставлять новые куки (comma-separated cookies). Допустим, у нас есть URL-параметр в заголовке с именем language. Мы его обрабатываем и записываем пользователю в куки выбранное значение language. Если атакующий вставит запятую, то он может вставить и дополнительные куки с любым именем.
Также в обходе CSRF-защиты могут посодействовать баги браузера. Например, в Firefox была возможность внедрять куки через SVG-картинку (CVE-2016-9078). Если у нас есть HTML-редактор и мы разрешаем пользователю вставлять image-теги, то атакующий может просто в SRC-атрибуте указать на SVG-картинку, которая установит нужные куки.
6. Change Content-Type
Некоторые разработчики считают, что если используется нестандартный формат данных в теле POST-запроса для общения с бэкендом, то это может спасти от CSRF. На самом деле это не так.
В качестве примера приведу уязвимость, которую я недавно нашел в одном очень популярном сервисе по управлению заметками.
Там использовался API, который использует Apache Thrift (бинарный формат данных) и куки для управления сессией. Допустим, чтобы добавить новую заметку, пользователь должен был отправить такой POST-запрос. В теле передавались бинарные данные и указывался Content-Type: application/x-thrift.
На самом же деле в бэкенде этот Content-Type не валидировался. Можно было его поменять на text/plain и с помощью XHR API эксплуатировать эту CSRF-уязвимость, просто передав бинарные данные в теле POST-запроса.
На самом деле защита, основанная на Content-Type — это очень плохой вариант защиты. Он в большинстве случаев обходится.
7. Non-simple Content-Type
Через HTML-форму или с помощью XHR API мы можем отправить следующие content types:
Довольно известный баг в браузере Chrome был найден в 2015 году, после этого примерно через месяц попал в публичный доступ, но был исправлен только в 2017 году. Этот баг позволял отправлять POST-запрос с любым Content-Type на другой origin с помощью API, которое называется Navigator.sendBeacon().
Как выглядела эксплуатация?
Мы создаем новый blob с нужным Content-Type и просто отправляем его с помощью Navigator.sendBeacon().
Еще один сценарий обхода, который до сих пор работает и поддерживается в браузерах — обход с помощью flash-плагина.
Даже есть сайт thehackerblog.com, где уже есть готовая флэшка, вы просто указываете URL, header, нужный Content-Type и данные, которые надо передать — отправляете, и в бэкенд улетает POST-запрос с нужным Content-Type.
Но есть одна хитрость — нельзя просто указать URL сайта, который мы атакуем. Нужно указать ресурс, который сделает redirect с кодом 307 на ресурс, который мы атакуем. Тогда это будет работать.
8. Spoof Referer
Последний вариант обхода защиты от CSRF основан на Referer. Есть баг в Microsoft Edge браузере, который до сих пор не исправлен и позволяет подделывать значение Referer. Но он работает, к сожалению, только для GET-запросов. Если атакуемый бэкенд не отличает GET от POST, то этот баг можно эксплуатировать.
Если все же нам надо POST, то есть небольшая хитрость. Мы можем отправить header Referer с помощью PDF плагина и FormCalc.
Где-то год назад можно было с помощью PDF плагина отправлять вообще любые header’ы, в том числе host, но потом Adobe закрыл эту возможность создав черный список header’ов. То есть если мы укажем Referer в заголовке, то этот заголовок просто не отправится.
Вообще FormCalc позволяет нам легально отправлять любой Content-Type. Если мы будем вставлять символы carridge return и line feed, то сможем добавлять в запрос дополнительные header’ы.
Это итоговая таблица. В столбцах представлены варианты защиты от CSRF, а в строках — методы обхода. В каждой ячейке указаны браузеры, в которых работает этот метод:
Наиболее кардинальный и работающий вариант защититься от CSRF-атак — это избавиться от куков и использовать header с токенами.
Но если вы все-таки не готовы отказаться от куков для управления пользовательской сессией:
Не прошло и полугода, а следующий хайлоад уже через месяц — Highload++ Siberia.
Хотим привлечь ваше внимание к некоторым из отобранных докладов: