Комментарии 31
Спасибо!
выставили авторизационную куку на домен второго уровня, а на серверной стороне стали проверять корректность переданной куки.
Кто-нибудь может объяснить, как делается серверная проверка? Предположим, у меня есть 2 сервера, один в России + ещё один в Германии. Как безопасно организовать процесс, какие технологии использовать?
P.S. Если это в блоге уже описывалось, буду рад ссылке, вопрос интересует, но в сетевых технологиях не силён.
Правильно сделать так, чтобы код, который обслуживает запросы пользователей, и код, который производит авторизацию запросов и работает с эккаунтами пользователями были изолированы друг от друга. Изоляция может быть в рамках одной машины, если это небольшой проект — разнести его по разным виртуальным хостам, системным эккаунтам, возможно, виртуальным машинам. В случае двух сильно удаленных хостов с негарантируемой связью это единственный вариант. Если проект большой — то чем больше уровней изоляции — тем лучше — т.е. желательно разносить не просто по разным виртуальным хостам, системным эккаунтам — но и по разным физическим машинам и сегментам сети.
Если вопрос о том, как безопасно связать 2 сервера — то ответ: через VPN.
Если вопрос о том, как безопасно связать 2 сервера — то ответ: через VPN.
куку просто надо подписывать одним ключем, который секретно храниться на двух серверах. Посмотрите как это реализовано в asp.net «из коробки» msdn.microsoft.com/en-us/library/ff649308.aspx
Ну и проверять пришедшую куку перед какой-то с ней работой естественно.
Ну и проверять пришедшую куку перед какой-то с ней работой естественно.
В mail.ru когда-то использовался похожий подход, но отказались от него довольно давно, хотя для многих проектов он вполне пригоден. Единственное замечание — с точки зрения разделения доступа использование симметричного ключа является ошибкой, т.к. ключ компрометируется при компрометации любого хоста. Правильно использовать ассиметричную криптографию или комбинацию.
Но у такого подхода есть и свои недостатки, например, достаточно сложно завершить сеанс пользователя на всех проектах одновременно.
Но у такого подхода есть и свои недостатки, например, достаточно сложно завершить сеанс пользователя на всех проектах одновременно.
Хороший пост. Раскрыта тема применения флагов Secure и HttpOnly. Надо взять себе на вооружения.
Спасибо, отличный пост. Must read всем причастным
> Mail.Ru — огромный портал, существующий более 15-ти лет. За это время мы прошли путь от небольшого веб-проекта до самого посещаемого сайта рунета.
vk.com?
vk.com?
vk.com действительно самый посещаемый сайт рунета, но не портал. Mail.Ru это не только главная страница или почта — это несколько сотен проектов. Месячная аудитория портала Mail.Ru – 59 млн. Для сравнения: ВКонтакте, — 52,1 млн (TNS, все население России в возрасте от 12 до 64 лет, март 2014 г.) и он только третий.
Я подумал, что Mail.Ru в какой-то момент был самым посещаемым сайтом рунета.
Спасибо за статью, возьму на заметку. Возник вопрос, не проще ли полностью поставить все проекты за принудительный HTTPS.
Очень правильный вопрос, спасибо.
Принудительный HTTPS (перенаправление + HTTP Strict Transport Security) обязательно нужен на критичных проектах, но он не отменяет необходимости реализовывать разделение сессий, потому что:
Т.е. надо использовать И принудительный https И разделение сессий.
Принудительный HTTPS (перенаправление + HTTP Strict Transport Security) обязательно нужен на критичных проектах, но он не отменяет необходимости реализовывать разделение сессий, потому что:
- Без разделения сессий компрометация одного из проектов приведет к компрометации всех проектов. В качестве примера можно привести Heartblead. Несколько проектов у нас были поддвержены этой атаке. По счастью, почту и центр авторизации «пронесло». Это как раз тот случай, когда нас спасло разделение сессий, т.к. компрометация второстепенных проектов не привела к компрометации учетных записей пользователей и почты.
- Если у кук нет флажка HTTPOnly, то XSS приводит к угону сессии, наличие https никак не влияет на это
- HTTP Strict Transport Security работает не во всех браузерах + не работает, когда пользователь долго не заходил на сайт.
Если у куки нет флажка Secure, то MitM все равно может угнать куку, заставив пользователя посетить незащищенный сайт, т.к. в запросе на незащищенный сайт кука будет присутствовать. Принудительный HTTPS в данном случае тоже не спасет.
Т.е. надо использовать И принудительный https И разделение сессий.
Зависит от проекта.
Там, где отдается много аудио/видео/больших картинок, будут очень большие накладные расходы на шифрование.
Как на серверах, так и на клиентах (а особенно на мобильных клиентах).
Т.е. вылезают проблемы из другой области.
Там, где отдается много аудио/видео/больших картинок, будут очень большие накладные расходы на шифрование.
Как на серверах, так и на клиентах (а особенно на мобильных клиентах).
Т.е. вылезают проблемы из другой области.
Накладные расходы есть, но при правильной организации их можно минимизировать. Мы тоже боялись что не справимся по нагрузкам, но на практике потребление ресурсов оказалось не таким страшным. Вот здесь статья, как почта переводилась на SSL.
SSL используется и в Облаке, где трафик передается десятками гигабайт, в том числе в мобильных клиентах, к явным проблемам с быстродействием это не приводит.
SSL используется и в Облаке, где трафик передается десятками гигабайт, в том числе в мобильных клиентах, к явным проблемам с быстродействием это не приводит.
Понятно, спасибо.
Честно говоря, я думал, у вас https терминируется каким-нибудь аппаратным решением :)
Мне кажется, серьёзные проблемы должны возникнуть при передаче видео, в том же HD.
Даже не столько у вас, сколько у клиента.
Если не секрет, как вы с видео поступили?
Честно говоря, я думал, у вас https терминируется каким-нибудь аппаратным решением :)
Мне кажется, серьёзные проблемы должны возникнуть при передаче видео, в том же HD.
Даже не столько у вас, сколько у клиента.
Если не секрет, как вы с видео поступили?
Очень полезно. Интересно было бы сравнить с авторизацией у гугл: как они это делают, какие плюсы/минусы.
Мне больше понравилась реализация на vk.com. Там основная кука сессии привязана к ip. Если украсть её, то она окажется бесполезна. В случае смены ip, происходит редирект на домен 3-го где установлена http only, secure кука, в случае её успешной проверки происходит обновление ip-зависимой куки. Вообще удивило что такой большой портал как mail.ru так поздно занялся решением такой большой проблемы.
Это почти тот же интересный и правильный вопрос, что обсуждался чуть выше, про то, что не проще ли внедрить принудительный https. Таким образом vk.com решается проблему относительно безопасного использования сессионных кук на небезопасном сайте без поддержки . Это в общем-то костыль, решение не надежно — если у вас в интернет-кафе отснифили привязанную к IP куку, то пока вы сидите в кафе и даже когда вы из кафе уходите, у похитителя остается доступ к сайту вместе с вашим прошлым IP адресом. Конечно, через некоторое время эта сессия проэкспайрится, но до тех пор ваш эккаунт доступен.
В почте Mail.Ru эта проблема решается именно путем принудительного https и HSTS, что гораздо надежней. vk.com уже внедряет https на добровольной основе и, надеюсь, в итоге придет к тому же решению с принудительным https + HSTS.
В этой же статье описывается решение несколько другой проблемы, с которой ВКонтакте пока не приходилось сталкиваться: это наличие в рамках одного домена второго уровня большого количества разных проектов, между которыми разделяется общая аутентификация пользователя. Требуется, чтобы ошибка в менее критическом проекте, например флеш-открытке с котиками, не затрагивала безопасность критических проектов, например ПочтыMail.Ru.
В почте Mail.Ru эта проблема решается именно путем принудительного https и HSTS, что гораздо надежней. vk.com уже внедряет https на добровольной основе и, надеюсь, в итоге придет к тому же решению с принудительным https + HSTS.
В этой же статье описывается решение несколько другой проблемы, с которой ВКонтакте пока не приходилось сталкиваться: это наличие в рамках одного домена второго уровня большого количества разных проектов, между которыми разделяется общая аутентификация пользователя. Требуется, чтобы ошибка в менее критическом проекте, например флеш-открытке с котиками, не затрагивала безопасность критических проектов, например ПочтыMail.Ru.
НЛО прилетело и опубликовало эту надпись здесь
Если по пунктам:
1й — не получится из-за X-Frame-Options на главной странице.
2й — shell of the future не обходит ограничения HTTPOnly, это реверс-шел на JS и имеет доступ только к тому, к чему имеет доступ JS. JS не имеет доступа к HTTPOnly кукам. Кроме того, загрузить внешний скрипт на наших основных проектов может быть немного сложно из-за CSP (Content Security Policy).
3й — НО, даже если полуилось загрузить скрипт и даже если бы скрипт имел доступ к кукам на главной странице, для того, чтобы получить доступ к сессии электронной почты, не достаточно куки с главной страницы, это как раз заслуга разделения сессий. Чтобы получить доступ к электронной почте, XSS должен быть именно в электронной почте.
И кстати, у нас есть программа поиска уязвимостей, за XSS в почте мы платим около $500, присоединяйтесь.
1й — не получится из-за X-Frame-Options на главной странице.
2й — shell of the future не обходит ограничения HTTPOnly, это реверс-шел на JS и имеет доступ только к тому, к чему имеет доступ JS. JS не имеет доступа к HTTPOnly кукам. Кроме того, загрузить внешний скрипт на наших основных проектов может быть немного сложно из-за CSP (Content Security Policy).
3й — НО, даже если полуилось загрузить скрипт и даже если бы скрипт имел доступ к кукам на главной странице, для того, чтобы получить доступ к сессии электронной почты, не достаточно куки с главной страницы, это как раз заслуга разделения сессий. Чтобы получить доступ к электронной почте, XSS должен быть именно в электронной почте.
И кстати, у нас есть программа поиска уязвимостей, за XSS в почте мы платим около $500, присоединяйтесь.
Очень похоже на kerberos.
Расскажите, пожалуйста, подробнее вот про это:
Не очень понял логику. Зачем «Токен проксируется проектом в центр авторизации, который по нему генерирует уже проектную куку для .project.mail.ru»? Токен проксируется обратно на auth.mail.ru для того чтобы убедиться, что это валидный токен, верно? Но почему куку генерирует центр авторизации, а не сам project.mail.ru? Ведь, насколько я понял, задача в том, чтобы выставить sdc-куку именно на уровне проекта. И если кука генерируется на уровне центра авторизации, то как она передается на сайт проекта? Грубо говоря: проект curl-ом соединяется с центром авторизации, а центр авторизации возвращает некторое значение, которое проект должен использовать для sdc-куки?
И еще вопрос: как запрос проекта «проксируется» в центр авторизации? Это curl-запрос не выходящий за рамки локальной сети, в которой работают все проекты или нет?
Когда пользователь заходит на сайт проекта, для которого у него еще нет авторизации, его запрос перенаправляется в центр авторизации. Центр авторизации аутентифицирует его по наличию куки .auth.mail.ru, генерирует одноразовый токен и перенаправляет на страницу проекта. Токен проксируется проектом в центр авторизации, который по нему генерирует уже проектную куку для .project.mail.ru.
Не очень понял логику. Зачем «Токен проксируется проектом в центр авторизации, который по нему генерирует уже проектную куку для .project.mail.ru»? Токен проксируется обратно на auth.mail.ru для того чтобы убедиться, что это валидный токен, верно? Но почему куку генерирует центр авторизации, а не сам project.mail.ru? Ведь, насколько я понял, задача в том, чтобы выставить sdc-куку именно на уровне проекта. И если кука генерируется на уровне центра авторизации, то как она передается на сайт проекта? Грубо говоря: проект curl-ом соединяется с центром авторизации, а центр авторизации возвращает некторое значение, которое проект должен использовать для sdc-куки?
И еще вопрос: как запрос проекта «проксируется» в центр авторизации? Это curl-запрос не выходящий за рамки локальной сети, в которой работают все проекты или нет?
Можно и curl, но на самом деле проще даже без курла — именно проксированием запроса (+служебные заголовки, например для передачи информации о клиенте, токена авторизации проекта и т.п.) и ответа — например балансировщиком или на reverse proxy. Центр авторизации в таком случае отвечает и за валидацию токена и за то, чтобы он был одноразовым. Это позволяет избежать лишнего дублирующего кода в проектах.
Как вариант, можно подписывать токен, но тогда логику проверки придется реализовывать в каждом проекте.
Как вариант, можно подписывать токен, но тогда логику проверки придется реализовывать в каждом проекте.
Спасибо. Уточните, пожалуйста, еще один момент.
Где определяется, что пользователь не авторизован? В браузере или на сервере?
Если речь о редиректе на уровне веб-сервера, то какой код для редиректа используется? 305, 307? Или авторизационная кука sdc-кука проверяется джаваскриптом (она ведь не httponly?) в браузере и им же делается редирект?
Когда пользователь заходит на сайт проекта, для которого у него еще нет авторизации, его запрос перенаправляется в центр авторизации.
Где определяется, что пользователь не авторизован? В браузере или на сервере?
Если речь о редиректе на уровне веб-сервера, то какой код для редиректа используется? 305, 307? Или авторизационная кука sdc-кука проверяется джаваскриптом (она ведь не httponly?) в браузере и им же делается редирект?
Проверяется на серверсайде, дается обычно 302 с запретом кэширования.
Спасибо большое за ответ. Еще один вопрос.
Я правильно понимаю, что токен передается просто GET-параметром на какой-то стндартный для проекта redirect url (примерно также сделано в oAuth2)? То есть схема выглядит так:
* юзер зашел на project.mail.ru, при этом он уже залогинен на одном из других проектов Mail.ru,
* его редиректит (с кодом 302) на auth.mail.ru,
* так как в auth.mail.ru есть его авторизационная кука его редиректит на, например, project.mail.ru/redirect?token=123456,
* project.mail.ru берет токен и передает его обратно на auth.mail.ru и в ответ получает сообщение, что все ок, токен валиден,
* после этого project.mail.ru выставляет свою авторизационную куку.
Верно я понял или нет?
Центр авторизации аутентифицирует его по наличию куки .auth.mail.ru, генерирует одноразовый токен и перенаправляет на страницу проекта.
Я правильно понимаю, что токен передается просто GET-параметром на какой-то стндартный для проекта redirect url (примерно также сделано в oAuth2)? То есть схема выглядит так:
* юзер зашел на project.mail.ru, при этом он уже залогинен на одном из других проектов Mail.ru,
* его редиректит (с кодом 302) на auth.mail.ru,
* так как в auth.mail.ru есть его авторизационная кука его редиректит на, например, project.mail.ru/redirect?token=123456,
* project.mail.ru берет токен и передает его обратно на auth.mail.ru и в ответ получает сообщение, что все ок, токен валиден,
* после этого project.mail.ru выставляет свою авторизационную куку.
Верно я понял или нет?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Разделяй и властвуй: как мы реализовывали разделение сессий на портале Mail.Ru