Пользователь
0,6
рейтинг
2 сентября 2014 в 16:07

Разработка → Типичные ошибки при защите сайтов от 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 чего-либо, кроме токенов.

Казалось бы, очень удобно использовать HTTP referer (https://ru.wikipedia.org/wiki/HTTP_referer) для защиты от атак. Если в этом заголовке не страницы с вашего домена, то запрос был подделан. Но не все так радужно. У небольшой части пользователей HTTP referer может быть пуст по разным причинам. Кроме того, он может быть подделан с использованием старых версий Flash, что подставляет под удар тех, кто очень долго ничего не обновлял на своем компьютере.

Как насчет использования капчи? Я слышал достаточно большое количество вопросов от разработчиков о возможности их использования для защиты от атаки. Мой однозначный ответ — нет. Во-первых, вы явно не будете заставлять пользователя вводить капчу на каждый чих: это приведет к ошибке № 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-атак стоит достаточно остро. Безусловно, этот список не является исчерпывающим. Я уверен, что можно найти еще несколько ошибок и способов их эксплуатации. Однако если вы проверите свои сайты на наличие проблем, описанных в этой статье, и исправите их, то значительно повысите защищенность проекта.
@pyrk2142
карма
8,0
рейтинг 0,6
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (93)

  • –1
    А еще можно просто не использовать GET и POST запросы для операций, связанных с изменением данных.
    • +2
      Как будто другие виды запросов более защищены…
      • 0
        Как вы подделаете PUT-запрос?
        • 0
          Так же, как и Referer.
          Старая версия флэша. Или ошибка в браузере, который еще не создан. Или ошибка в версии флэша, которую еще не выпустили.
          • 0
            Ну вы же понимаете, что это очень маловероятный вариант.
    • +3
      А что вы предложите использовать?
      • –1
        Автор имел в виду, что, к примеру, PUT запрос можно послать ajax'ом, но невозможно отправкой формы (CSRF-атакой). В принципе прикольная идея. Не уверен в практичности, но прикольная.
        • +5
          Сама идей, на мой взгляд, довольно интересная. Но у нее есть два недостатка:

          1) Повышается сложность разработки: вместо того, чтобы добавить новое скрытое поле в форму, генерировать токен и проверять его на стороне сервера (реализация всех этих действий требует не очень много кода и совсем небольшое вмешательство в уже существующий), вам необходимо написать посредника для получения данных из формы (чем сложнее форма, тем больше кода и потенциальных ошибок) и отправки их на сервер. На серверной стороне вам надо будет переписать код, отвечающий за прием данных и их валидацию. И необходимо убедиться, что не происходит обработки POST/GET запросов, изменяющих данные пользователя. Я наблюдал много схожих ошибок у тех, кто активно использует AJAX на сайте: на сервере нет проверки, пришли ли данные через AJAX или обычную отправку формы. Это просто рай для любителя CSRF.

          2) Вам надо следить за возможными обновлениями браузеров: я видел некоторое количество предложений разрешить использовать тот же PUT в обычных формах. Если же вы правильно реализовали механизм токенов, то вам не надо этого боятся. Проверку токена на серверной стороне не сможет отменить ни один браузер.
          • 0
            Да в общем-то наоборот, это позволяет надежно исключить практически все указанные ошибки — тип запроса или наличие заголовка можно проверять не в коде скрипта, а на балансере, реверс прокси или веб-сервере, что позволяет исключить человеческий фактор и ошибки программистов. К тому же, поскольку доступ в таком случае управляется CORS, при необходимости легко разрешить некоторым доверенным сайтам делать межсайтовые запросы.

            Вторая проблема, если честно, кажется надуманной, но легко устраняется проверкой X-Requested-With.
            • 0
              Я не спорю, что эти недостатки можно обойти. Но эти методы я бы отнес к разряду лучших практик для достаточно крупных сайтов. Например, для многих сайтов, расположенных на shared-хостинге, использование балансера, реверс прокси или фильтрации на уровне сервера весьма затруднительно. А добавление токенов значительно проще.

              Или пример на основе реального проекта вашей компании. Речь идет о LOTRO. Когда на сайте этой игры всплыли возможности для CSRF, разработчики сначала добавили проверку на Referer, так они поступили с каждой новой CSRF, которая была найдена. Потом им сообщили о возможности использования одного токена для разных пользователей (что-то вроде токена применялось в некоторых формах, алгоритм выбора которых я так и не понял). Через некоторое время они применили несколько попыток сделать защиту от кликджекинга. А уже после этого они, наконец-то, добавили токены во все критичные запросы на сайте. Как вы понимаете, речь про замену метода запросов на отличный от GET/POST даже не шла.
              • 0
                Редиректить на ошибку при неправильном типе запроса/отсутствующем заголовке можно средствами стандартного mod_rewrite.

                Ограничения есть, но они другие: этот подход годится только для сайтов, где все запросы аяксовые.
                • 0
                  Изначальный вопрос в этой ветке — использование не POST/GET для изменения пользовательских данных.
                  А еще можно просто не использовать GET и POST запросы для операций, связанных с изменением данных.

                  По вашим же словам, данный способ подходит только для сайтов, использующих AJAX. Для других сайтов надо либо заменять все запросы на AJAX (это весьма трудоемко), либо применять другие методы защиты. Использование методов, отличных от POST/GET не является универсальным решением. Так что вопрос создания надежной системы токенов остается важным.
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              В каком случае не спасет проверка на аякс?
              Злоумышленник же не может отправить CSRF запрос AJAXом с другого домена (если не стоят разрешающие заголовки на сервере). Но может отправить форму.
              • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            >> Повышается сложность разработки

            Не вижу принципиальной разницы между обработкой POST или PUT, PATCH, DELETE, whatever (если знаешь, что такое php://input).

            >> Если же вы правильно реализовали механизм токенов, то вам не надо этого боятся

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

            >> Вам надо следить за возможными обновлениями браузеров: я видел некоторое количество предложений разрешить использовать тот же PUT в обычных формах

            Это да, я согласен. Но не думаю, что на это пойдут.
            • 0
              Вообще я не утверждаю, что это супер-пупер-серебряная пуля, но как одну из возможных стратегий защит от CSRF рассматривать стоит.
          • 0
            на сервере нет проверки, пришли ли данные через AJAX или обычную отправку формы
            Вы имеете ввиду http заголовок X-Requested-With? Но ведь его можно подделать на клиенте. Или есть какие то другие способы проверить это?
    • 0
      . (повтор)
    • –7
      Не, так не надежно. Если не хотите, что бы у вас украли что-то из интернета, не передавайте эти данные в интернет вот и всего делов-то ))
    • 0
      Можно и POST с GET, но ставить дополнительный заголовок / проверять его наличие.
      • 0
        Кто помешает злоумышленнику установить дополнительный заголовок при осуществлении атаки? Полагаю, что имеет смысл, только если в заголовке будет передаваться все тот же секретный ключ
        • 0
          CORS помешает, для заголовков отличных от Accept и Accept-Language делается preflight-request.
  • +5
    Кроме того, он может быть подделан с использованием старых версий Flash, что подставляет под удар тех, кто очень долго ничего не обновлял на своем компьютере.
    ОЧЕНЬ старой.
  • 0
    Объясните пожалуйста, зачем нужна проверка этого CSRF-токена. Чем опасно обращение с другого сайта? Допустим у меня есть некий API, через который пользователь взаимодействует с удаленным сервером. Взаимодействовать он может как через веб интерфейс, так и через приложение. Допустим, что если в первом случае проверка CSRF оправдана, то во втором зачем она нужна, если есть сессия например? И нужна ли вообще? Или CSRF используется только для доступа с браузера? А зачем, если, например, можно просто сделать апи и неважно, какой там клиент на другой стороне: браузер или десктоп приложение. Надеюсь, ясно выразился и удалось разобрать, какая информация меня интересует )
    • 0
      В статье идет речь исключительно о формах. Если у вас REST-API, который сам по себе защищен, а сайт только клиент, то беспокоится, в общем не о чем. Другое дело, что когда клиентом является сайт, то формы на нём так или иначе будут, и опять же из них можно перехватить и использовать во зло.
      Надеюсь, более-менее объяснил :)
    • 0
      Предположим, что пользователь на Вашем на сайте может выполнять какие-то действия только авторизовавшись. Тогда, если он уже авторизован (сессия запущена), при попадании на сайт злоумышленника, с этого сайта от его имени может быть отправлен POST-запрос на изменение каких-либо данных, или GET-запрос на получение приватной/конфиденциальной информации.
    • +4
      Допустим, есть некоторый сайт, где в админке есть функция удаления этого самого сайта (ну, чтобы страшнее было). Допустим, эта функция доступна по GET-запросу на URL example.com/admin/deleteall?b=yes

      Злоумышленник знает о существовании этой ссылки. Он вводит ее в любой сокращатель ссылок, получая безобидную ссылку goo.gl/cC68N6 Теперь он отправляет эту ссылку по скайпу админу сайта, админа редиректит на example.com/admin/deleteall?b=yes — и, если админ был залогинен в админке, весь сайт удаляется. Атака удалась.

      Если используется POST — то атака становится сложнее, но не перестает быть возможной от этого: form.submit() еще никто не отменял.

      Необходимым условием является возможность для злоумышленника составить правильный запрос, чтобы потом передать его для выполнения жертве. Сама передача, как видно, осуществляется очень просто. CSRF-токен является элементом запроса, который злоумышленник не способен предсказать. Если обновить админку сайта, чтобы ссылка на удаления была вида example.com/admin/deleteall?b=yes&token=/token/, где /token/ — уникальный секрет, либо одноразовый, либо привязанный к сессии пользователя — то злоумышленник не сможет угадать его, составить запрос и в итоге не сможет провести атаку.
  • 0
    По поводу последнего пункта весьма спорно. В качестве примера возьму свою любимую ссылку /logout/ на «выход» с ресурса. Рассмотрим пример классической атаки: модератор форума не может забанить пользователя за сообщение в ветке — каждый раз он получает ошибку и потом теряет сессию. Хитрый пользователь просто разместил в сообщении bb-код [img]http://example.com/logout[/img].
    • +1
      А где у хитрого пользователя POST?
      • 0
        У нас не особо хитрый разработчик который сделал logout через GET в этом примере.
    • 0
      К данному примеру у меня есть два замечания:

      1) Как и говорили выше, логичнее делать такие запросы через POST, а пользователям не давать возможность вставлять необработанный HTML в сообщения. И, конечно, стоит использовать токен.

      2) С формальной точки зрения, данный пример опровергает бесспорность первого пункта. Если же подходить менее формально, то ситуация несколько другая: хотя токен и не был одноразовым, при выходе с сайта он стал таковым: когда пользователь покинул сайт, его старый токен должен стать недействительным, а новый он получит при следующем входе на сайт. В данном конкретном случае раскрытие такого токена не позволяет провести атаку с его использованием.
  • –5
    Я только одного не понимаю, народ пишет про все эти методы защиты, referer, другой тип запроса, токен и прочее…

    какой в этом вообще смысл, последнее время когда совершается подобная атака, все запросы делают вообще сервером, соответственно проставляют любые заголовки в запрос, распарсивают страницу и находят любой токен с нее…

    по сути взломщик полностью эмулирует деятельность пользователя…

    как раз тема с капчей более менее рабочая, хоть и требует доп действий от пользователя. Еще возможно собирать метрики пользователей и как то пытаться проверять поведение: «робот не робот»
    • +3
      Смотрите, тут дело несколько в другом. CSRF атака нужна не для того, чтобы эмулировать действия пользователя и оставлять всякие рекламные сообщения на сайте. CSRF предназначена для того, чтобы выполнить от имени пользователя (злоумышленник не имеет доступа к его аккаунту) запрос на сайт (этот запрос пользователь тоже не хочет выполнять). Подобные методы не защитят вас от спамеров. Но помогут защитить ваших пользователей от CSRF, чтобы те не лишились своих аккаунтов.
      • –3
        это конечно ясно, но сейчас очень много смежных атак при которых делается фишинг страница, пользователь самостоятельно вводит в ней данные, а уже далее их уже с ними эксплуатируют сервис, в таком случае как раз капча очень не плоха
        • +1
          CSRF-атак становится все меньше исключительно потому что от них учатся защищаться. Убери защиту — и это быстро обнаружат.

          PS капчу можно показать на той самой фишинговой странице, чтобы пользователь не только подарил свои данные злоумышленнику — но и капчу заодно разгадал.
        • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Десятый пункт неоднозначен: точно так же можно предположить что пользователь сохранит веб страницу и отправит ее кому-то. В этом случае так же будут скомпрометированы все токены в формах.
  • 0
    >> 8) Предсказумые токены.

    А зачем генерить токен на основе каких-то данных? Почему нельзя взять просто рандомную строку?
    • 0
      Рэндомные токены будут теряться при прерывании сессии (пишете вы длинную статью на хабр, а за это время сессия истекла и токен больше недействителен). Поэтому и возникает соблазн сделать токен таким, чтобы пользователь мог его использовать даже в случае прервавшейся сессии.
      • 0
        При прерывании сессии пользователь не сможет сохранить статью даже с валидным токеном…
        • 0
          Если в куках имеются данные для автологина, то без проблем сможет. Более того, даже не заметит что она прерывалась.
      • 0
        В алгоритме генерации токена на основе пользовательских данных должна быть некая условно случайная величина, чтобы токен все время новый получался. Например, метка времени. Чтобы проверить валидность токена, нужно где-то хранить эту метку времени. Если ее хранить в сессии, то в вашем примере токен протухнет тоже. Если хранить в БД, тогда мы и рандомные токены можем точно так же хранить в БД.
        • 0
          Я не говорил что так надо делать. Я отвечал на вопрос «какие проблемы решает данный подход». Читайте внимательнее.
          • 0
            Вы написали

            >> Рэндомные токены будут теряться при прерывании сессии

            Я вам доказал, что при прерывании сессии рандомные токены будут протухать не более, чем обычные. Поэтому изначальный вопрос:

            >> А зачем генерить токен на основе каких-то данных? Почему нельзя взять просто рандомную строку?

            а точнее «Чем рандомные токены хуже нерандомных» остается открытым.
            • +1
              Нерэндомные токены генерируются на основе нерэндомных данных, как следует из названия. Раз данные нерэндомные, значит они повторяемые и токен можно в сессии не хранить.
              Простой пример:
              token=md5(date+user_id+userpass)
              В течение суток данный токен будет валиден для пользователя user_id независимо от того, сколько сессий он откроет. Метку времени хранить при этом нигде не надо, как следует из псевдокода выше.
              Я ответил на вопрос?
              • –1
                Что такое date? Текущая дата? Т.е. если пользователь сел писать статью в 23:59, то через минуту его токен протухнет?
                • +1
                  Не придуривайтесь. Вы хотите чтобы я вам сделал «хороший образец плохого подхода»? Сдвиньте смену даты на пять утра, когда 99,9% населения спит, или привяжите токен к фазам луны, или к настроению своего кота — это ваши личные программистские трудности. Автор написал что так делать нельзя, я написал что так делать нельзя. Вы все равно просите сделать именно так и чтобы при этом вам это решение еще понравилось.
                  И да. Протухнет токен только в случае разрыва сессии.
                  • 0
                    >> Сдвиньте смену даты на пять утра, когда 99,9% населения спит или привяжите токен к фазам луны или к настроению своего кота

                    Статью может писать житель Калифорнии, у которого в этот момент 5 вечера.
                    • +1
                      В профиле пользователя можно указать его часовой пояс.
                      Вы пытаетесь придумать условия, в которых проявится недостаток нерэндомных токенов, при том что этот недостаток является фундаментальным для рэндомных. И ничего — как-то живут люди. Получают новый токен и отправляют форму повторно. Тоже самое будет и для нерэндомного, только во много раз реже.
                      • 0
                        Короче. Мне надоело с вами спорить. У вас сплошные костыли.
                        • 0
                          А я с вами и не спорил. Это вы мне хотели что-то доказать, даже не потрудившись прочитать что я вам написал.
      • 0
        Посмотрел сейчас как создаются токены в Symfony и Drupal. В обоих случаях использются сессии.
        • 0
          Э-э-э… а что вы ожидали увидеть?
          • 0
            Как раз это и ожидал. А что означает тройное «Э»?
            • 0
              Значит что я несказанно удивлен вашим комментарием. Так что даже не сразу нашелся что ответить.
              • 0
                Хм, а что в нём такого нескзанно удивительного? Вы считаете что не существует способов создать токен без использования сессий?
                • 0
                  Не считаю. И не припоминаю чтобы я это утверждал. Или вам все равно с кем дискутировать на желаемую тему?
                  • 0
                    И не припоминаю чтобы я это утверждал.
                    Я не говорил что вы это утверждали.

                    Значит что я несказанно удивлен вашим комментарием. Так что даже не сразу нашелся что ответить.
                    Можете всё таки объяснить причину такого удивления?
                    • 0
                      Могу. Вот представьте, иду я по улице, вы ко мне подходите и заявляете:
                      — Я проверил под краном и в бачке унитаза — и там и там вода мокрая.
                      — Э-э-э… а какую воду вы там ожидали увидеть?
                      — Как раз такую и ожидал. А что означает ваше «Э»?
                      — Значит что я несказанно удивлен вашим комментарием.
                      — Вы считаете что вода может быть сухой?
                      — Не считаю. И никогда не заявлял подобного.
                      и далее по тексту.
                      Вот так я вижу сейчас наш диалог. Может вы меня с кем-то перепутали?
                      • 0
                        У вас в предпоследнем предложении диалога преднамеренная ошибка которая меняет весь его смысл. Я спрашивал полностью обратное. И аналогия с мокрой водой мягко говоря притянута за уши.

                        Кстати, вот пример генерации токена без использования сессии.
                        • 0
                          Вы пытаетесь мне доказать (а может опровергнуть — я так и не понял) то, чего я, по вашим собственным словам, не говорил (и я тоже помню что этого не говорил). Какое отношение это доказательство/опровержение имеет ко мне?
                          • 0
                            Не пытаюсь я ничего доказать, просто интересно стало почему вас так сильно удивил комментарий о том что Симфони и Друпал используют сессии для генерации токенов. Вы к сожалению так внятно и не ответили.
                            • 0
                              Он меня удивил, потому, что совершенно не имел отношения к обсуждаемому вопросу. Да и к самой статье он отношение имеет весьма далекое.
                              • 0
                                Хм, тогда вообще не понятно. Теряется логическая связь между токенами через сессии и мокрой водой в бочке.

                                Э-э-э… а что вы ожидали увидеть?
                                я несказанно удивлен вашим комментарием. Так что даже не сразу нашелся что ответить.
                                Я проверил под краном и в бачке унитаза — и там и там вода мокрая.

                                В итоге получилось всего лишь:

                                Он меня удивил, потому, что совершенно не имел отношения к обсуждаемому вопросу.


                                Ладно, возможно я действительно ничего не понимаю тут.
  • 0
    Ошибся веткой. Удалено
  • –1
    Каким образом можно осуществить CSRF атаку если все административные действия на сайте осуществляются только с помощью POST запросов?
    • 0
      Навскидку
      1) Форма на другом сайте, подсунутая допустим админу.
      2) Если есть допустим XSS, а она бывает часто, в связке дает возможность слать через Ajax запросы POST
      Скорее всего есть и другие варианты
      • 0
        Впринципе первого способа достаточно, хотя с GET конечно все намного проще.
      • 0
        2) Если есть допустим XSS

        Если есть XSS, то вся CSRF-защита улетучивается: можно и токен угнать и запросы слать с этой страницы (обход проверки реферера).
        • 0
          Навскидку
          1) Привязка по IP
          2) Куки недоступные из JS
          Скорее всего есть и другие варианты
          • –1
            Привязка по IP не поможет. Недоступность куков из JS, конечно, спасет — но это отменит саму возможность ajax-запросов. А если разрешать ajax-запросы — то при наличии XSS злоумышленник воспользуется тем же самым механизмом.
            • –1
              Я в том смысле, что если есть Basic авторизация или проверка по IP в админку с куками мы не зайдем, нужно делать CSRF от админа с POST запросом со страницы на которой есть XSS.
              А недоступность cookies из JS не отменяет остальные действия JS. Сейчас я говорю о флаге HTTPonly (https://www.owasp.org/index.php/HttpOnly)
              • –1
                А я в том смысле, что нет смысла делать CSRF от админа, если можно сделать XSS от админа.
                • –1
                  Что такое XSS от админа?
                  Что вы им сделаете?
                  • 0
                    Отошлю на сервер любой запрос, с IP адреса админа, с куками админа — и с авторизацией админа.
                    • 0
                      Для этого нужно, как минимум, физическое присутствие к компьютеру админа.
                      • –1
                        Не нужно. Достаточно XSS.
                        • –1
                          Специально для Вас сделал тестовую площадку, в хидерах браузерную защиту от xss отключил.
                          link
                          Получите, пожалуйста, через XSS секретную cookie с именем admin и приведите пример запроса.
                          Код страницы:

                          <?php header("X-XSS-Protection: 0"); ?>
                          <html><head></head><body>
                          <?php
                          setcookie ( 'admin' , 'secretToken' , 0 , '/', null,false , true );
                          setcookie ( 'notSecret' , 'ThisIsCookieNotSecretWithHttpOnly0' , 0 , '/', null,false , false );
                          echo $_GET['c'];
                          ?></body></html>
                          

                          • –1
                            Зачем мне секретная кука, если я могу выполнить запрос от вашего имени, подсунув вам эту ссылку.
                            • –1
                              То, что это и есть ничто иное как csrf
                              • 0
                                Нет, это XSS. Это было бы CSRF, если бы я сразу дал ссылку на slus.name/deleteallsite.php
                                Разница — принципиальная. Наличие активного скрипта на клиентской стороне делает защиту токенами бесполезной — злоумышленник вытащит его с первой же формы.
                                • –2
                                  Похоже смысла спорить с Вами нет вообще, выше приведены примеры когда это не так. Csrf это не атака, это класс уязвимостей, как и xss. Использоваться они могут как совместно так и раздельное.
                • 0
                  Пример сплойта для JavaScript, при ограничении по IP и Basic авторизация к папке admin и выставленном флаге HTTPOnly, при всех действиях в админке через POST
                  <script>
                  $.post(
                    "/admin/do.php?act=add_user",
                    {
                      name: "admin",
                      pass: 12345
                    }
                  );
                  </script>
                  

                  Данный пример именно связка XSS + CSRF, при необходимости добавляется допустим воровство токенов.

                  Приведите пример «можно сделать XSS от админа», без CSRF в таких же условиях, который может привести к компроментации приложения?
                  Единственный вариант на ум приходит, это фейковая страница.
                  • 0
                    При чем тут CSRF вообще? XSS может быть и хранимой, к примеру.
                    • –1
                      CSRF это отсутствие проверок при добавлении нового пользователя в данном примере через POST запрос.
                      Не важно в данном контексте активная или пассивная XSS.
    • 0
      А в чем техническая проблема?
      Вы создаете на своем сайте страницу, где в скрытом фрейме загружается другая страница с формой. В этой форме все нужные данные для атаки вставлены в скрытые поля. А эта форма автоматически отправляется через JS после ее загрузки.
  • 0
    На своём проекте (asp.net mvc) сделал для защиты от csrf-атаки две вещи:

    1) Все формы генерируются только через extension метод, который повторяет сигнатуру оригинального метода (Html.BeginForm), в нём инкапсулировано добавление токена (средствами самого asp.net, т.е. велосипед не строил)
    2) Все ajax запросы идут через прокси функцию, которая к каждому post запросу добавляет токен (просто ищет его в форме и выдирает. подразумевает, что каждая страница, с которой может исходить post запрос имеет форму)

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

    Если кому интересен код — пишите.
    • 0
      Я бы посоветовал еще и заменить стандартный хелпер Html на свою реализацию — чтобы никто оригинальный метод случайно не вызвал.

      Это делается просто: находите в Web.config строку <pages pageBaseType="System.Web.Mvc.WebViewPage"> и заменяете базовый класс на свой, унаследованный от старого — и там переопределяете свойство Html. Не забыть сделать то же самое с типизированным вариантом.
    • –1
      Злоумышленник откроет код формы и возьмет оттуда токен.
      • 0
        Защита направлена на пресечение подмены лица, которое запрос шлёт. Чуть выше, в комментах, эта тема более детально раскрыта. Но в двух словах ещё раз: Если не использовать csrf токены, то любой POST/GET запрос может быть отправлен ВАМИ с чужой помощью. Т.е. вы просто открываете ссылку «котятки.рф/лалала» и всё, у вас удаляется сайт/перечисляются деньги на карточку/ставится статус в соц сети — всё что угодно. И самое главное — вы даже не заметите ничего, всё будет выглядеть до боли естественно. И хорошо, если сервер проверяет referer, но опять же, как писали выше — это не спасёт от чуть более продвинутой атаки с использованием flash старых версий.
      • 0
        Я его не пущу за свой компьютер! А на другом пусть открывает сколько влезет — у него будет другой токен.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.