Как защитить виджеты от поддельных запросов

Допустим, у вас есть виджет JavaScript, который должен запускать запрос к вашему веб-приложению, если и только если пользователь хочет щелкнуть по нему. Вы не хотите, чтобы этот запрос был уязвим для CSRF, поэтому вы пишете на страницу iframe. Исходя из правил наследования происхождения, родительский сайт не сможет прочитать токен CSRF. Однако как насчет кликджекинга (или лайкджекинга)? Из-за CSRF вы должны быть в пределах iframe, и там x-frame-options не могут помочь, и то же самое верно для frame-busters.

Атакующий собирается применить SVG-маску для iframe после загрузки виджета. Эта маска сделает iframe невидимым. На этом этапе злоумышленник может либо изменить размер фрейма так, чтобы он соответствовал размеру страницы, либо сделать так, чтобы этот теперь невидимый фрейм следовал за курсором. В любом случае, когда пользователь нажимает в любом месте страницы, iframe получает событие click и игра заканчивается.

Таким образом, существует двойственность, кажется, вы застряли между CSRF и Clickjacking. Какое лучшее решение (если есть) этой проблемы?

6 ответов

Решение

При нажатии на виджет необходимо открыть всплывающее окно с новой страницей - iframe недостаточно хорош, это должно быть новое окно - которое полностью находится под контролем вашего веб-приложения. Подтвердите действие, что бы это ни было, на этой странице.

Да, это несколько не элегантно, но нынешняя архитектура веб-безопасности не дает вам лучших вариантов.

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

OWASP упоминает в своей электронной таблице предотвращения CRSF, что одним из предварительных условий для защиты токена CSRF является отсутствие атаки XSS.

На мой взгляд, это также должно включать в себя клик-джеккинг, поскольку токен CSRF, даже скрытый внутри iframe, не может защитить от клик-джеккинга. Запрос подделывается прямым кликом пользователя.

Таким образом, в конце концов, мы на самом деле не застряли между CSRF и Clickjacking - защита CSRF предназначена для другого типа атак, где на стороне атакующего гораздо меньше энергии.

Итак, на вопросы, которые вы упоминаете, касающиеся clickjacking и CSRF:

  • Как лучше всего решить эту проблему (если есть)? - Лучшая защита для кликджекинга на стороне клиента - это открыть новую вкладку браузера или окно браузера с измененным размером со страницей с вашего сайта и подтвердить действие там, как упоминает @Zack. Это то, что делает кнопка твиттера, и в этом сценарии не может быть подделки запроса.

  • Таким образом, существует двойственность, кажется, вы застряли между CSRF и Clickjacking - защита CSRF не предназначена для таких случаев, как XSS или атаки с использованием clickjacking, она эффективна только против менее мощных атак (электронная почта с вредоносной ссылкой, размещение вредоносной ссылки на форуме и т. Д.)..)

Не существует хорошего программируемого решения для кликджекинга. Некоторые компании предъявляют иск спаммерам в качестве защиты от перехвата кликов. Другие предпочитают показывать всплывающие окна после того, как пользователь нажал внутри iframe, хотя это ухудшает взаимодействие с пользователем, особенно в случае нажатия одной кнопки. Это именно то, что Twitter делает для кнопки "Retweet". В настоящее время Facebook использует этот подход для кнопки "Мне нравится", запрашивая подтверждение при поступлении запросов из доменов, занесенных в черный список. Я слышал, что робот Google выполняет некоторую эвристику при щелчке, индексируя страницы с помощью кнопки "+1" (проверка вычисленных стилей, перекрытия элементов и т. Д.)…

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

Таким образом, iframe сможет использовать токен CSRF, как и положено, что защитит от этого типа атак, пока родительский фрейм не сможет прочитать токен.

Clickjacking, как я уверен, вы знаете, это совершенно другой тип атаки, чем CSRF и нуждается в другой защите.

Действительно, если виджет очень важен, чем реализовывать двухфазную аутентификацию. Используйте http://twilio.com/ чтобы позвонить пользователю и попросить его ввести пин-код. Или отправьте электронное письмо пользователю со ссылкой для подтверждения. Или попросите пользователя подтвердить действие при следующем входе пользователя на сайт вашего виджета.

Если бы у вас был контроль над родительским фреймом, у вас было бы больше возможностей. Тогда это будет вопросом защиты XSS.

Обновить после того, как правильный ответ был выбран

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

- ОБНОВЛЕНИЕ-- Когда вы говорите "виджет", если вы имеете в виду что-то за пределами вашего приложения, с которым взаимодействуют неаутентифицированные люди, игнорируйте этот ответ. Я перечитал ваш вопрос, и вы никогда не указали, что вы подразумеваете под "виджетом". У нас есть все виды "виджетов", которые есть в нашем приложении. Я думал, что это то, о чем вы говорили, все внутри приложения, с которым взаимодействовали только аутентифицированные пользователи. Если это так, то этот ответ - то, что рекомендует OWASP.

- Первоначальный ответ:"Вы не хотите, чтобы этот запрос был уязвим для CSRF, поэтому вы пишете на страницу iframe". Нет, не создавайте iframe, таким образом, вы можете выполнить обычную рекомендацию OWASP для защиты от создания фреймов.

Чтобы защитить от хэша CSRF некоторые значения, включите их в форму (или данные POST ajax), а затем проверьте значение хеша на серверной части. Если это соответствует, это с вашего сайта. Чем более конкретные данные вы можете поместить в хеш, тем лучше.

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

И это легко добавить везде, даже если ваш сайт уже написан (при условии, что на вашем сайте есть какой-то один фрагмент кода, включенный во все страницы, например, нижний колонтитул). Сделайте хэшированное значение и поместите его в скрытый тег где-то в нижнем колонтитуле. Затем вы можете использовать jQuery для динамического добавления этого хеш-значения, скрытого для всех форм на странице. И вы можете использовать jQuery.ajaxPrefilter, чтобы автоматически добавлять его во все POST-файлы ajax, если вы выполняете публикацию ajax, а не публикацию обычной формы. Мы защищаем некоторые очень большие сайты, которые уже были закодированы таким образом.

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

Если это похоже на путь, который вы хотите выбрать, я мог бы показать код jQuery для этого. Что касается того, что вы хэшируете, как вы хотите проверить это на бэкенде и т. Д.... все зависит от того, используете ли вы ColdFusion, PHP, PL/SQL (psp) и т. Д.... Я могу указать вам на правильное направление, если его один из тех.

Из-за CSRF вы должны быть в пределах iframe...

Нет. Вы не можете исправить CSRF с помощью файлов cookie и других не относящихся к делу уловок. Неважно, где вы их положили.

Таким образом, существует двойственность, кажется, вы застряли между CSRF и Clickjacking. Какое лучшее решение (если есть) этой проблемы?

Чтобы исправить CSRF, вы должны устранить угрозу, исправив сервер, на котором есть инъекция или вредоносный код, остановив фишинговую электронную почту и т. Д. В отсутствие благоприятной среды необходимо повторно подтвердить подлинность пользователя (или предоставить другую проблему). / ответ для обеспечения интерактивного пользователя). Увидеть:

Это напоминает Clickjacking, используйте X-Frame-Options или код разрыва фрейма в Javascript. Но я не думаю, что они тоже надежны. Увидеть:

Другие вопросы по тегам