Невозможно определить csrf что это

Шпаргалки по безопасности: CSRF

Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить 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 что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

Важно помнить, что данный атрибут стоит использовать как дополнительную меру защиты, а не как способ обойтись без использования 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 – нет, то запрос может считаться валидным

Источник

Типичные ошибки при защите сайтов от CSRF-атак

Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

В настоящее время в сфере обеспечения безопасности веб-сайтов и приложений возникла очень интересная ситуация: с одной стороны, некоторые разработчики уделяют особое внимание безопасности, с другой, они напрочь забывают о некоторых видах атак и не считают ошибки, позволяющие выполнить данные атаки, уязвимостями. Например, к такой категории можно отнести CSRF (Сross Site Request Forgery). Эта атака позволяет производить различные действия на уязвимом сайте от имени авторизованного пользователя. Если вы не слышали о таком, то я рекомендую прочитать соответствующую статью в Википедии, чтобы иметь общее представление об этом виде атак. Основная часть статьи предназначена тем, кто обеспокоен правильной защитой своих сайтов от CSRF.

Замечание 1: если подходить формально, то CSRF является атакой, а не уязвимостью, как и XSS. Уязвимостью является неправильная обработка входных данных, а CSRF это использует.
Замечание 2: если какие-то ошибки показались вам очевидными и не заслуживающими упоминания, то я рад за вас. Однако данный материал основан на реальных уязвимостях крупных сайтов, а каждый пункт показывает ошибку какой-либо команды разработчиков, обернувшуюся дырой в безопасности.

Список ошибок:

1) Полностью отсутствует защита от CSRF.

По своему опыту могу сказать, что в настоящее время это — самая распространенная ошибка. Ее можно встретить как на малопосещаемых блогах, так и на крупных проектах. Единственная уважительная причина не использовать защиту от данного вида атак — сайт не хранит никакие пользовательские данные, а вы не используете панель администратора для редактирования материалов.

2) Защищены не все запросы.

Я бы поставил эту ошибку на второе место по распространенности. На многих сайтах, где реализована какая-либо защита от CSRF, можно найти уязвимые запросы. Например, если вы воспользуетесь поиском Хабра habrahabr.ru/search/?q=CSRF, то увидите значительное количество статей, повествующих о найденных уязвимостях на тех сервисах, где есть защита.
Вы должны защищать абсолютно все запросы, которые изменяют что-либо на сайте. Вы добавили токен в форму смены адреса электронной почты, и злоумышленник не сможет завладеть аккаунтом вашего пользователя, изменив от его имени почту, а затем и пароль? Здорово. Вот только такая мера бесполезна, если можно просто отправить запрос на перевод денег с аккаунта жертвы на кошелек атакующего, минуя вашу защиту.
Удобство обеспечения безопасности — одна из причин использовать только метод POST для запросов, изменяющих данные пользователя. Если вы следуете этому совету, то необходимо просто убедиться, что все POST-запросы содержат надежный и правильный токен. Об этом речь пойдет ниже.

3) Использование для защиты от CSRF чего-либо, кроме токенов.

Как насчет использования капчи? Я слышал достаточно большое количество вопросов от разработчиков о возможности их использования для защиты от атаки. Мой однозначный ответ — нет. Во-первых, вы явно не будете заставлять пользователя вводить капчу на каждый чих: это приведет к ошибке № 2. Во-вторых, далеко не все способы реализации капч обеспечат вас должной защитой, которую злоумышленник не сможет обойти. Поскольку эта тема является весьма спорной и актуальной, в дальнейшем я посвящу ей отдельную статью.

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

Другим распространённым способом защиты является механизм, при котором с каждой сессией пользователя ассоциируется дополнительный секретный ключ, предназначенный для выполнения запросов. Пользователь посылает этот ключ среди параметров каждого запроса, и перед выполнением каких-либо действий сервер проверяет этот ключ. Преимуществом данного механизма, по сравнению с проверкой Referer, является гарантированная защита от атак данного типа. Недостатками же являются: требования возможности организации пользовательских сессий и динамической генерации HTML-кода активных страниц сайта.

4) Отсутствие проверки анти-CSRF токена при обработке запроса.

Подобную ошибку я встречал на сайтах весьма серьезных компаний, чья безопасность должна быть на высоте.
В самом запросе токен есть, а при его обработке он не проверяется. Можно вставить в это поле любую строку, запрос все равно будет корректно обработан. Комментировать тут особенно нечего, надо только указать, что применение функции isset() php.net/manual/ru/function.isset.php для проверки токена совершенно недопустимо.

5) Частичная проверка анти-CSRF токена.

Данную ошибку я встретил сразу на нескольких крупных сайтах рунета в разных вариациях. Например, один из сайтов использовал токены вида «Имя_пользователя.Текущее_время.Длинное_случайное_число». При этом проверялось только соответствие имени пользователя в токене и логина того, от чьего имени был отправлен запрос. Это немного усложняет атаку, но не делает ее невозможной.

6) Возможность использовать один токен для разных пользователей.

Данную ошибку я встретил один раз, но на достаточно крупном сайте, так что считаю необходимым упомянуть ее. Злоумышленник мог зарегистрировать новый аккаунт на сайте, скопировать токен из исходного кода страницы и использовать его для CSRF. Не допускайте такой ошибки, так как она полностью уничтожает все плюсы токенов на вашем сайте.

7) Недостаточная длина токена.

Ваш токен должен быть настолько длинным, чтобы злоумышленник потратил на его подбор как минимум столько же времени, сколько и на подбор пароля пользователя. Я встречал токены из 2 символов, они не сильно помогут, если кто-то очень сильно захочет осуществить CSRF-атаку.

8) Предсказумые токены.

При разработке алгоритма генерации токена обязательно используйте случайные данные в токене (совет актуален, если вы разрабатываете всю систему с нуля. В случае использования фреймворка или CMS вы должны полагаться на их разработчиков). Поверьте, токен вида «md5(user_id)» — очень плохая идея.

9) Отсутствие токенов в админ-панели или системе для сотрудников техподдержки.

Даже если весь доступный вашим пользователям сайт защищен от CSRF, то не стоит забывать про панель администратора. В одной известной в узких кругах биллинг-системе было много CSRF именно в панели администратора (хотя они были и в публичной части системы, но это не так важно). И любой, кто знал структуру запросов, мог использовать CSRF-атаку на сотрудника техподдержки и получить доступ к данным всех клиентов компании, использующей данную биллинг-систему. Единственная проблема — необходимо узнать структуру запросов: для этого можно использовать социальную инженерию, скачать копию в открытых источниках или просто взломать менее защищенный сайт, использующий такую же систему.

10) Передача токенов в открытом виде, особенно в GET-запросах.

На нескольких сайтах я видел ситуации, когда токены пользователей передавались в открытом виде: если токен содержится в адресе страницы, то пользователь может скопировать ссылку целиком и разместить ее где-нибудь, даже не подозревая об опасности. Вам не нужно сильно беспокоиться о скрытой передаче токенов только тогда, когда они одноразовые, а пользователь может случайно раскрыть только использованный токен. Однако это все равно не очень хорошо, так как сигнализирует о некоторых проблемах с архитектурой приложения: например, вы используете GET, а не POST для запросов, изменяющих пользовательские данные.

Наличие этих ошибок даже на крупных и серьезных сайтах показывает, что проблема защиты от CSRF-атак стоит достаточно остро. Безусловно, этот список не является исчерпывающим. Я уверен, что можно найти еще несколько ошибок и способов их эксплуатации. Однако если вы проверите свои сайты на наличие проблем, описанных в этой статье, и исправите их, то значительно повысите защищенность проекта.

Источник

CSRF-уязвимости все еще актуальны

CSRF (Сross Site Request Forgery) в переводе на русский — это подделка межсайтовых запросов. Михаил Егоров (0ang3el) в своем докладе на Highload++ 2017 рассказал о CSRF-уязвимостях, о том, какие обычно используются механизмы защиты, а также как их все равно можно обойти. А в конце вывел ряд советов о том, как правильно защищаться от CSRF-атак. Под катом расшифровка этого выступления.

О спикере: Михаил Егоров работает в компании Ingram Micro Cloud и занимается Application security. В свободное время Михаил занимается поиском уязвимостей и Bug hunting и выступает на security-конференциях

Дисклаймер: приведенная информация является сугубо мнением автора, все совпадения случайны.
Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

В том, что CSRF-атаки работают виноват этот Cookie-монстр. Дело в том, что многие веб-приложения используют куки (здесь и далее считаем уместным называть cookies по-русски) для управления сессией пользователя. Браузер устроен так, что, если у него есть куки пользователя для данного домена и пути, он их автоматически отправляет вместе с HTTP-запросом.

Cookies

Куки — это небольшой фрагмент данных, который веб-сервер отправляет клиенту в виде name=value в HTTP-заголовке c названием «Set-Cookie». Браузер хранит эти данные на компьютере пользователя, и всякий раз при необходимости пересылает этот фрагмент данных веб-серверу в составе HTTP-запроса в HTTP-заголовке с названием «Cookie».

Куки могут иметь различные атрибуты, такие как: expires, domain, secure, httponly:

Впервые куки появились в браузере Netscape в далеком 1994 году. До сих пор многие веб-приложения используют их для управления сессией пользователя.
Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

Рассмотрим, как работает классическая Сross Site Request Forgery (CSRF) атака.

Допустим, в нашем веб-приложении есть возможность изменять адрес доставки у пользователя, и оно использует куки для управления сессией.

У нас есть HTML-форма, которую пользователь должен заполнить: ввести адрес и нажать кнопку «Сохранить». В результате в бэкенд полетит POST-запрос с HTML-формой. Мы видим, что браузер автоматически поставил туда сессионные куки пользователя. Бэкенд, когда получит такой запрос, посмотрит, что есть такая сессия, это легитимный пользователь, и изменит ему адрес доставки.

Что может сделать атакующий?
Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

Он может на своем сайте attacker.com разместить такую HTML-страничку, которая на самом деле сабмитит HTML-форму на сайт example.com. Так как браузер автоматически вставляет куки пользователя в HTTP-запрос, то бэкенд просто не поймет, является ли данный запрос легитимным — результат ли это заполнения формы пользователем, или это CSRF-атака — и поменяет адрес доставки для пользователя на значение, которое выгодно для атакующего.

Есть другой вариант CSRF-атаки с использованием XHR API. Если о CSRF-атаке с использованием HTML-форм слышали многие, то о данном способе знают меньше, но он тоже работает.
Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

Обратите внимание на атрибут withCredentials, который заставляет браузер автоматически отправлять куки пользователя. Так как значение Content-type равно application/x-www-form-urlencoded, то браузер данный запрос отправит без CORS options preflight request, и опять CSRF-атака будет работать.

Рассмотрим более наглядно, как это происходит.
Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить 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 что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

Рассмотрим, какие варианты защиты от CSRF существуют и как работает каждый из вариантов защиты.

Поэтому, теперь давайте поговорим о 8 способах обхода защиты, которые можно использовать на практике.
Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

Сценарии обхода:

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:
Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

Этот файл содержит 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-запроса.
Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

На самом деле защита, основанная на 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-плагина.
Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

Даже есть сайт 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.
Невозможно определить csrf что это. Смотреть фото Невозможно определить csrf что это. Смотреть картинку Невозможно определить csrf что это. Картинка про Невозможно определить csrf что это. Фото Невозможно определить csrf что это

Где-то год назад можно было с помощью PDF плагина отправлять вообще любые header’ы, в том числе host, но потом Adobe закрыл эту возможность создав черный список header’ов. То есть если мы укажем Referer в заголовке, то этот заголовок просто не отправится.

Вообще FormCalc позволяет нам легально отправлять любой Content-Type. Если мы будем вставлять символы carridge return и line feed, то сможем добавлять в запрос дополнительные header’ы.

Это итоговая таблица. В столбцах представлены варианты защиты от CSRF, а в строках — методы обхода. В каждой ячейке указаны браузеры, в которых работает этот метод:

Наиболее кардинальный и работающий вариант защититься от CSRF-атак — это избавиться от куков и использовать header с токенами.

Но если вы все-таки не готовы отказаться от куков для управления пользовательской сессией:

Не прошло и полугода, а следующий хайлоад уже через месяц — Highload++ Siberia.

Хотим привлечь ваше внимание к некоторым из отобранных докладов:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *