- PVSM.RU - https://www.pvsm.ru -
В этой статье я расскажу о реализациях разного функционала (преимущественно, на веб-сервисах) для обеспечения безопасности пользователей на примере «гигантов» современной IT индустрии. Данный материал будет полезен разработчикам, архитекторам, тим-лидам и менеджерам при постановке задач схожего функционала. Реализации в статье разработаны командами профессионалов, проверены временем и сотнями миллионами пользователей (а также большим количеством хакеров), хоть и никаких гарантий, что именно данный вариант реализации — абсолютно правильный и 100% безопасный, конечно же нет. Информация основана на личном анализе этих ресурсов.
Наиболее удачный и интересный вариант реализован в ВК. Описывал вкратце здесь [1]. Пароль вводится на главной странице сайта, но action формы ведёт на поддомен (login.vk.com), там выставляется кука для текущего домена (login.vk.com) и для vk.com (remixsid). Если с кукой на «главном» домене что-то не то (изменена, не совпал последний IP и т.п), автоматически происходит редирект на login.vk.com. И если пароль действительно вводился в этом браузере, то в нём будет persistent-кука (которая выставилась при вводе пароля), по которой произойдет автоматический вход. Если же её нет (к примеру, куки увели через XSS) то на аккаунт не пустит. Так же ведется запись последних активных сессий — 6 штук, который считаются «живыми» и которые можно завершить в личном кабинете, что очень удобно. У гугла тоже отдельный домен для авторизации. И так как у него много различных сервисов, то при авторизации ещё передается список сервисов, куда пускать с этими cookie.
О ней говорят налево и направо и в общем случае принято реализовывать OTP отсылкой через SMS. Снова в пример возьмем Google. И проблема первая: связь не доступна, что делать пользователю? Для этого реализовали два решения:
Авторизация сотрудников Google на их внутреннем портале login.corp.google.com [3] также происходит с использованием двухфакторной авторизации, но можно еще использовать usb-токен (аналогия с банками) для авторизации.
А что делать, если Ваш сервис предоставляет API для мобильных устройств? И некоторые приложения, работающие вне браузера, несовместимы с двухэтапной аутентификацией и не могут запрашивать коды подтверждения? Здесь же, по примеру Google, решили проблему следующим образом. Можно сгенерировать «пароль приложения» [4]. Вводится имя приложения и разово выдается (больше нигде и никогда не отображется) пароль для приложения, который нужно ввести вместо пароля.
Логичным продолжением будет этот пункт. Используя стандартную схему с высылкой ссылки на почту, что лучше делать, генерировать новый пароль самому или дать возможность ввести его пользователю? Вообще, более предпочтителен второй способ (Google). Но если Вы решили использовать первый — генерируйте пароль ну никак не менее 7-8 символов (буквы/цифры/хотя бы один спец. символ). Буквально на днях анализировал таблицу с пользователями и паролями, где пароль выставлялся автоматом (md5, 6 символов, [a-zA-Z0-9]). И за копейки получал их в чистом виде. Да и вообще, рекомендовано: sha* и две «соли». (т.е. вида sha*($stat_salt.$password.$email)), т.е. когда при полном дампе базы данных ни один пароль всё равно не получится расшифровать, так как будет неизвестна статичная «соль» (которая, например, зашита в коде). Но это тема другого разговора.
Важно еще понимать, что нужно еще и правильно его реализовать. Пример: Facebook, прошлый год. Восстановление пароля через SMS. Нам присылают код на телефон, мы его вводим и меняем id конечного пользователя в форме. В итоге — меняем пароль любому юзеру. Как можно было не проверять ID юзера, которому мы меняем пароль? Как можно было не сопоставлять высланный код в SMS и id пользователя? Epic fail.
Защиту от CSRF верно реализовывать с помощью «скрытых» токенов (<input type = «hidden»>). Но как их верно генерировать? Google, при каждой авторизации, выдает токен на сессию и сохраняет её в Cookie. Т.е. смотрит cookie, смотрит, что пришло в форме, если всё ок — работаем дальше. То есть один токен на все действия в рамках одной сессии. Неправильно спрашивать пользователя при несовпадении токенов, действительно ли он хотел выполнить это действие («привет» разработчикам сервиса, которые только что узнали себя в этой статье), так как это очень сомнительно (пользователь может кликнуть автоматом ) + есть обходы подобных «просьб с уточнениям». Вконтакте поступили по другому — они генерируют на каждое действие один токен, который основывается на id текущего пользователя, id действия и некоторого id «цели» (пользователь, номер сообщества/паблика и т.п.). Но, к сожалению, не везде его проверяют.
Весь пользовательский контент нужно заливать на отдельный домен. Это может спасти от множества угроз. У Google это googleusercontent.com, у VK — vk.me. На примере статьи XSS'им iOS устройства на примере софта от Facebook, Google, ВКонтакте [5], когда «особенность» целой платформы для эксплуатации уязвимости не может нанести никакого вреда — ещё один показатель, чем важен отдельный (изолированный, никаких cookie) домен для пользовательского контента.
Сейчас многие ресурсы активно ведут разработку с учетом CSP. Например Yandex не так давно реализовал вариант почты с полной поддержкой CSP. CSP — это такой заголовок, который сообщает браузеру, откуда (с каких адресов) и какой контент (картинки, скрипты) можно загружать. В итоге, когда атакующий даже находит способ провести XSS атаку, ему не удаётся переслать какие-либо данные напрямую на другой сервер, или вообще выполнить inline скрипты. Конечно, находятся и обходы, например можно сгенерировать картинку и встроить в неё js и, при возможности, залить на один из разрешенных доменов. И обратиться к ней <script src "...image.gif>, пример [6].
Говоря снова о HTTP заголовках (статья [7]), нельзя не упомянуть о HSTS. Одно дело просто его отправлять.
Другое дело, что существует pre-shared лист в Chrome и Firefox, среди которых перечислены домены, которые в обязательном порядке нужно посещать через HTTPS — src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security_state_static.json [8].
Можно отправить заявку на добавление вашего ресурса на почту 
Довольно часто (а порой и необходимо) обращаться к услугам других сервисов (регистрация доменов, мониторинг и т.п.). И вроде как существует цикл (например, раз в 3 месяца) когда на всех подобных ресурсах меняется пароль. Хорошая практика.
Возможно где-то еще у «гигантов» (у меня нет информации) используется доступ по VPN до рабочих ресурсов (частая практика и в маленьких компаниях) и какие-нибудь еще механизмы защиты. Если знаете таковые — делитесь в комментариях :)
upd: Возможно [9], что Apple использует VPN.
Автор: BeLove
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/bezopasnost/52746
Ссылки в тексте:
[1] здесь: http://habrahabr.ru/post/156517/
[2] accounts.google.com/b/0/SmsAuthSettings: https://accounts.google.com/b/0/SmsAuthSettings
[3] login.corp.google.com: https://login.corp.google.com
[4] «пароль приложения»: https://accounts.google.com/IssuedAuthSubTokens?hl=ru
[5] XSS'им iOS устройства на примере софта от Facebook, Google, ВКонтакте: http://habrahabr.ru/company/dsec/blog/202784/
[6] пример: http://sergeybelove.ru/tools/img_js.html
[7] статья: http://habrahabr.ru/post/168739/
[8] src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security_state_static.json: http://src.chromium.org/viewvc/chrome/trunk/src/net/http/transport_security_state_static.json
[9] Возможно: https://twitter.com/isox_xx/status/423063347378933760
[10] Источник: http://habrahabr.ru/post/209042/
Нажмите здесь для печати.