Безопасность как искусство
229,19
рейтинг
14 января 2014 в 15:55

Разработка → Результаты исследования методов аутентификации и некоторых механизмов защиты от WEB-атак на примере Google, VK и других

О чем топик?


В этой статье я расскажу о реализациях разного функционала (преимущественно, на веб-сервисах) для обеспечения безопасности пользователей на примере «гигантов» современной IT индустрии. Данный материал будет полезен разработчикам, архитекторам, тим-лидам и менеджерам при постановке задач схожего функционала. Реализации в статье разработаны командами профессионалов, проверены временем и сотнями миллионами пользователей (а также большим количеством хакеров), хоть и никаких гарантий, что именно данный вариант реализации — абсолютно правильный и 100% безопасный, конечно же нет. Информация основана на личном анализе этих ресурсов.


Авторизация


Наиболее удачный и интересный вариант реализован в ВК. Описывал вкратце здесь. Пароль вводится на главной странице сайта, но action формы ведёт на поддомен (login.vk.com), там выставляется кука для текущего домена (login.vk.com) и для vk.com (remixsid). Если с кукой на «главном» домене что-то не то (изменена, не совпал последний IP и т.п), автоматически происходит редирект на login.vk.com. И если пароль действительно вводился в этом браузере, то в нём будет persistent-кука (которая выставилась при вводе пароля), по которой произойдет автоматический вход. Если же её нет (к примеру, куки увели через XSS) то на аккаунт не пустит. Так же ведется запись последних активных сессий — 6 штук, который считаются «живыми» и которые можно завершить в личном кабинете, что очень удобно. У гугла тоже отдельный домен для авторизации. И так как у него много различных сервисов, то при авторизации ещё передается список сервисов, куда пускать с этими cookie.

Двухфакторная авторизация


О ней говорят налево и направо и в общем случае принято реализовывать OTP отсылкой через SMS. Снова в пример возьмем Google. И проблема первая: связь не доступна, что делать пользователю? Для этого реализовали два решения:

  • Оффлайн генерация OTP через приложение на мобильном устройстве. Первым шагом идёт синхронизация веб-сайта и мобильного приложения, вводом специального кода. После пароли на сервере и на мобильном телефоне сопоставляются по времени (лучше, чтобы телефон был синхронизирован по NTP). Т.е. на мобильном устройстве, в оффлайне, выводится пароль, который подойдет в качестве OTP (каждую минуту — новый пароль). В итоге в любом месте, при рабочем мобильном устройстве мы можем залогиниться без получения SMS/принятия звонка от Google.
  • Разовые, уже сгенерированные, пароли. На странице accounts.google.com/b/0/SmsAuthSettings можно получить и распечатать пароли, которые всегда (по одному разу) подойдут при запросе OTP кода. Можно распечатать и положить в бумажник

Авторизация сотрудников Google на их внутреннем портале login.corp.google.com также происходит с использованием двухфакторной авторизации, но можно еще использовать usb-токен (аналогия с банками) для авторизации.

А что делать, если Ваш сервис предоставляет API для мобильных устройств? И некоторые приложения, работающие вне браузера, несовместимы с двухэтапной аутентификацией и не могут запрашивать коды подтверждения? Здесь же, по примеру Google, решили проблему следующим образом. Можно сгенерировать «пароль приложения». Вводится имя приложения и разово выдается (больше нигде и никогда не отображется) пароль для приложения, который нужно ввести вместо пароля.

Восстановление пароля


Логичным продолжением будет этот пункт. Используя стандартную схему с высылкой ссылки на почту, что лучше делать, генерировать новый пароль самому или дать возможность ввести его пользователю? Вообще, более предпочтителен второй способ (Google). Но если Вы решили использовать первый — генерируйте пароль ну никак не менее 7-8 символов (буквы/цифры/хотя бы один спец. символ). Буквально на днях анализировал таблицу с пользователями и паролями, где пароль выставлялся автоматом (md5, 6 символов, [a-zA-Z0-9]). И за копейки получал их в чистом виде. Да и вообще, рекомендовано: sha* и две «соли». (т.е. вида sha*($stat_salt.$password.$email)), т.е. когда при полном дампе базы данных ни один пароль всё равно не получится расшифровать, так как будет неизвестна статичная «соль» (которая, например, зашита в коде). Но это тема другого разговора.

Важно еще понимать, что нужно еще и правильно его реализовать. Пример: Facebook, прошлый год. Восстановление пароля через SMS. Нам присылают код на телефон, мы его вводим и меняем id конечного пользователя в форме. В итоге — меняем пароль любому юзеру. Как можно было не проверять ID юзера, которому мы меняем пароль? Как можно было не сопоставлять высланный код в SMS и id пользователя? Epic fail.

Защита от CSRF


Защиту от CSRF верно реализовывать с помощью «скрытых» токенов (<input type = «hidden»>). Но как их верно генерировать? Google, при каждой авторизации, выдает токен на сессию и сохраняет её в Cookie. Т.е. смотрит cookie, смотрит, что пришло в форме, если всё ок — работаем дальше. То есть один токен на все действия в рамках одной сессии. Неправильно спрашивать пользователя при несовпадении токенов, действительно ли он хотел выполнить это действие («привет» разработчикам сервиса, которые только что узнали себя в этой статье), так как это очень сомнительно (пользователь может кликнуть автоматом ) + есть обходы подобных «просьб с уточнениям». Вконтакте поступили по другому — они генерируют на каждое действие один токен, который основывается на id текущего пользователя, id действия и некоторого id «цели» (пользователь, номер сообщества/паблика и т.п.). Но, к сожалению, не везде его проверяют.

Отдельный домен для контента


Весь пользовательский контент нужно заливать на отдельный домен. Это может спасти от множества угроз. У Google это googleusercontent.com, у VK — vk.me. На примере статьи XSS'им iOS устройства на примере софта от Facebook, Google, ВКонтакте, когда «особенность» целой платформы для эксплуатации уязвимости не может нанести никакого вреда — ещё один показатель, чем важен отдельный (изолированный, никаких cookie) домен для пользовательского контента.

Content Security Policy


Сейчас многие ресурсы активно ведут разработку с учетом CSP. Например Yandex не так давно реализовал вариант почты с полной поддержкой CSP. CSP — это такой заголовок, который сообщает браузеру, откуда (с каких адресов) и какой контент (картинки, скрипты) можно загружать. В итоге, когда атакующий даже находит способ провести XSS атаку, ему не удаётся переслать какие-либо данные напрямую на другой сервер, или вообще выполнить inline скрипты. Конечно, находятся и обходы, например можно сгенерировать картинку и встроить в неё js и, при возможности, залить на один из разрешенных доменов. И обратиться к ней <script src "...image.gif>, пример.

HSTS


Говоря снова о HTTP заголовках (статья), нельзя не упомянуть о HSTS. Одно дело просто его отправлять.
Другое дело, что существует pre-shared лист в Chrome и Firefox, среди которых перечислены домены, которые в обязательном порядке нужно посещать через HTTPS — src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security_state_static.json.
Можно отправить заявку на добавление вашего ресурса на почту

Аккаунты на 3rd-party ресурсах


Довольно часто (а порой и необходимо) обращаться к услугам других сервисов (регистрация доменов, мониторинг и т.п.). И вроде как существует цикл (например, раз в 3 месяца) когда на всех подобных ресурсах меняется пароль. Хорошая практика.

Возможно где-то еще у «гигантов» (у меня нет информации) используется доступ по VPN до рабочих ресурсов (частая практика и в маленьких компаниях) и какие-нибудь еще механизмы защиты. Если знаете таковые — делитесь в комментариях :)

upd: Возможно, что Apple использует VPN.
Автор: @BeLove
Digital Security
рейтинг 229,19
Безопасность как искусство

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

  • +1
    Ну про остальных не знаю, но вот у ВК с безопасностью проблемы.
    Да, защита от XSS есть, CSRF-токены там всякие.
    На самом деле, не все так радужно. Много сказано на эту тему, но пока они не будут поощрять за уязвимости, ничего хорошего не выйдет.
    Может это только мое мнение, тут не мне судить, так сказать.
    Но факт остается в том, что я находил довольно много разных нехороших штук, там, у них под капотом.
    Чего стоит только моя XSS в Августе 2012 Хабр (если мне сейчас 17, то сколько было тогда?).
    НО(!), у них такая политика. С этим ничего не поделаешь. Мы живем в таком мире, где просто не существует идеальной защиты.
    Но почему не предпринимать попытки для ее создания (читай Баг баунти), я не понимаю.

    П.с: Кстати, FB меня кинул, с CSRF ;)
    • +3
      Ну, не знаю.
      Мне они просто отвечали «спасибо» и очень быстро правили (не раз). Это уже лучше, чем полный игнор :) + сроки исправления радуют.
      • 0
        Вот тут с вами согласен, за скорость действительно, уважаю их.
        UPD: Или вы про ФБ?
        • +3
          Все верно, про ВК :)
          А вот ФБ порой вообще не отвечают. Но есть инфа (от сотрудника службы безопасности ФБ), если не отвечают, надо отвечать на свое же письмо, у них отчет «прыгает» при этом вверх.
          • +1
            АП баг репорта, так сказать
  • 0
    А про аутентификацию на web-API расскажете что-нибудь интересное?
    • +3
      Да, конечно.

      • При использовании и парсинге XML запросов нужно запретить парсинг сущностей и не допустить XXE уязвимости
      • Если используется sha1/sha512/md5 (и т.п.) при генерации токена ключ подставлять справа от конкатенируемых параметров, чтобы не допустить length extension attack
      • Использовать https для API. При этом, если используете Web API в мобильном приложении — проверяйте сертификат на корректность (как в браузере, когда выскакивает окошко, если сертификат не валиден). А еще лучше — зашить отпечатки сертификата, чтобы усложнить анализ протокола (т.е. даже при добавлении своего сертификата глобально на телефон, использование приватного ключа при сниффинге трафика ничего не дало). Т.е. только при модификации приложения стало возможным анализировать ваш API (встречается крайне редко, даже у «гигантов» индустрии)
      • 0
        Спасибо, полезный ответ!
        Хотя, откровенно говоря, я намекал на полноформатную статью об особенностях проэктирования аутентификации для web-API ;)
  • +13
    Заголовок
    Как защищаются гиганты: о безопасности Google, VK и других
    не соответствует содержимому.
    Нажимая на ссылку, я ожидал описание механизмов и средств защиты, архитектуры подсистем информационной безопасности и все такое.
    А получил некий сумбурный набор информации об аутентификации в веб-приложениях и парочку примеров о защите от некоторых видов web-атак.
    • 0
      Предложите более корректное.
      • –4
        Те компании, про которые я знаю, что рассказать, не разрешают мне этого делать (NDA), про те, о которых мне нечего рассказать — я молчу. Поэтому и не пишу топики с такими заголовками.
        • +7
          Я лишь предложил Вам предложить более корректное название статьи, при чем тут NDA?
          • +3
            А, черт, я думал было предложено написать свою статью :) Прошу прощения, туплю под конец рабочего дня.
            Можно что-то наподобие «Результаты исследования методов аутентификации и некоторых механизмов защиты от WEB-атак на примере Google, VK и других»
            • +2
              Ничего страшного, спасибо! С заголовком согласен, корректней будет, исправил.
  • 0
    (т.е. вида sha*($stat_salt.$password.$email))

    Чуть лучше использовать динамическую соль. Пруф.
    • 0
      Почта в данном случае — динамическая соль, для каждого юзера разная.
      Да, можно завести еще поле в базе с самой динамической солью, но если дампается база — то и она тоже будет дампнута.
      • +2
        Извиняюсь, взгляд зацепился за $stat_salt.
        Кстати, тогда при таком методе нужно не забывать хешировать пароль при смене email'а если она возможна.
  • +3
    def offtop = {
    Топик на злобу дня. Начинаю делать веб-приложение для личного сервиса и встал вопрос об авторизации. Несмотря на миниатюрность размеров приложения, хочу сделать его насколько возможно безопасным, так как оно работает с моими реальными финансовыми данными. С фронтами дел почти не имел, посему прошу направить в нужную сторону при поиски инфы. Есть ли какой-то свод алгоритмов, направленных на снижение угроз перебора, xss и пр.?
    Гугл конечно молодец, но фильтровать тонны инфы по непрофильной для меня области в рамках личного проекта не улыбается.
    }
    • 0
      На чём пишите то?
      • 0
        Scala + play 2.2
        • 0
          Как сделаете — потом просто пишите в личку, гляну :)
          Скалу на пентесте встречал один раз, использовалась только как бэкенд.
          • 0
            Спасибо за предложение!

            Вообще я хотел бы некое описание потенциальных проблем с рекомендациями по их предотвращению. Насколько понимаю, все типы уязвимостей общие и не зависят от конкретной платформы. Поэтому предполагаю существование некой шпаргалки или свода лучших практик. По сути паттерны безопасности при разработке и администрировании.
  • 0
    «когда при полном дампе базы данных ни один пароль всё равно не получится расшифровать, так как будет неизвестна статичная «соль» (которая, например, зашита в коде)»
    Посоветуйте где лучше хранить соль и пароли, ведь если «сломают» и уведут дамп, то увести текущие исходники и конфиги (там где хранятся пароли и соль) будет так же не сложно достать.
    • +1
      Не стоит думать что соль удастся спрятать от кражи. Если злоумышленник украл базу, есть большая вероятность что он доберется и до исходников.
      Зачем вообще нужна соль? Чтобы, получив базу с захешированными паролями, злоумышленник не смог использовать заранее сгенерированные таблицы хешей.
      Однако, если соль статическая и известна злоумышленнику, он может начать перебор атакуя при этом каждый из хешей.
      Если соль динамическая и для каждого пароля своя, атаковать перебором нужно будет каждый хеш отдельно.
      Подробнее тут.

      В общем генерируйте соль для каждого пароля и кладите в базу рядом, либо используйте в качестве соли уникальные данные (тут правда есть нюансы + соль не должна быть короткой).
  • 0
    Спасибо за статью, отлично когда такого рода продвинутая и актуальная информация достается так просто!

    Что-то не очень понятно насчет сохранения пользовательского контента на отдельном домене:
    * если нет cookie, каким образом контен пользователя будет «обезопасен» от неавторизированного доступа? Секретными урл-ками?
    * что нужно чтобы проэксплуатировать такую уязвимость как XSS? Нужно чтобы как-то пользователь контент злоумышленника как HTML/JS?
    • 0
      Спасибо за отзыв!
      Ответ на первый вопрос:
      Если контент в итоге должен остаться публичным — то проблем нет, отдавайте просто ссылку на него.
      Если нет (например — вложения почты) — то гугл генерит временные токены для доступа («живут» около минуты).
      Второй вопрос не понял, о чём речь?
      • 0
        Про второй вопрос: я пытался представить себе как злоумышленник мог бы воспользоваться такой фичей как upload произвольного контента не в соц. сетях. Могу себе представить что на gmail или vk это можно сделать как-то рассылая ссылки на плохую html страницу пользователям того же gmail или вконтакте, в надежде что они откроют страницу и запустят «злой» javascript под своей авторизацией. А вот на каком-нибудь другом проекте где пользователи не знают о существовании друг друга, добиться того чтобы какой-то другой пользователь открыл плохой контент может быть сложновато.

        Временные токены это и есть некоторый аналог cookies, но доступ на одну минуту кажется каким-то маленьким. В принципе наверное можно делать токены в урле на 5-10 минут, их нельзя будет похитить заставив пользоваеля открыть публичную ссылку на этом выделенном для пользовательского контента домене.
  • 0
    Как лучше всего делать API для авторизации для мобильного/десктопного приложения? Открытие страницы в браузере не самый лучший вариант.
    • 0
      Делай OAuth2 и давай нужным приложениям(клиентам) grant_type=password возможность. Тогда можно без страничек обойтись.

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

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