Домены Yandex Object Storage внесены в Public Suffix List
В Яндекс Облаке мы постоянно улучшаем безопасность предлагаемых сервисов.
Недавно была одобрена заявка на включение наших доменов в Public Suffix List (список публичных
- суффиксов). Список включённых доменов:
- yandexcloud.net
- storage.yandexcloud.net
- website.yandexcloud.net
Что меняется
Указанные домены получают свойства доменов верхнего уровня (top-level domain, TLD), как, например, домены .ru,.рф, .com. Это приведет к следующим изменениям:
- Браузеры не будут сохранять сookie, установленные на домены Yandex Object Storage. Это блокирует возможность влиять на логин-сессию пользователя.
- Браузеры не позволят поменять заголовок запроса origin страницы на корневые домены. Это лишает злоумышленников возможности получать доступ к контенту через смену origin страницы.
Ниже мы подробно рассказываем о том, какие возможные угрозы безопасности блокируются включением доменов в список публичных суффиксов.
cloud.yandex.ru/docs/storage/concepts/bucket
Управление файлами cookie для доменов Yandex Object Storage
Если раньше на сайте в Yandex Object Storage c помощью кода ниже можно было установить значение сookie для всех бакетов сразу, то теперь это не сработает.
<body>
<script>document.cookie = 'CookieName=CookieValue;MaxAge=300;Domain=website.yandexcloud.net'</script>
</body>
Добавляя и управляя сookie на родительском домене можно манипулировать сессией, в которой окажется залогинен пользователь, или влиять на контент, который он видит. Блокируя эту возможность мы повышаем безопасность Yandex Object Storage.
Изменение заголовка запроса origin страницы
Теперь браузеры не позволят менять заголовок запроса origin страницы на корневые домены. Код ниже не сработает:
<body>
<script>document.domain='yandexcloud.net'</script>
</body>
Оказывается, данным кодом можно пользоваться на личных доменах для обхода правила ограничения домена (Same Origin Policy) при прямом обращении из javascript-кода страницы в iframе, расположенный на поддомене [1, 2]. Но в облаке бакеты могут принадлежать разным клиентам, и возможность сменить origin при использовании несёт риски безопасности.
К примеру, пусть у некой корпорации используется данная схема:
Для логина в систему пользователь заходит на corp-bucket1.website.yandexcloud.net, где ему показывается форма ввода пароля.
<!DOCTYPE html>
<html>
<body>
<h1>corp-bucket1<h1><hr>
<iframe name="auth" src="https://corp-bucket2.website.yandexcloud.net/" frameborder="1" onload="setLocation()"></iframe>
<script>
document.domain = "website.yandexcloud.net";
function setLocation() {
auth.login_origin.value = document.location;
}
</script>
</body>
</html>
Форма ввода пароля расположена на другом поддомене — // corp-bucket2.website.yandexcloud.net/
<!DOCTYPE html>
<html>
<body>
<h1>corp-bucket2<h1><hr>
<div id="login-form">
<form action="https://corp.example.com" method="POST">
<input id="login" value="" placeholder="john.doe@corp.internal">
<input id="password" value="" placeholder="************" type="password">
<input id="login_origin" value="" type="hidden">
<input type="submit" value="Sign In">
</form>
</div>
<script>document.domain='website.yandexcloud.net';</script>
</body>
</html>
И, так как пользователю не хочется вводить пароль каждый раз, то он сохраняет его в браузере, а браузер автоматически подставляет пароль. Со временем число сайтов у компании растёт, и вместе с логином и паролем принимается решение передавать дополнительную информацию — например, на каком сайте пользователь залогинился. Для этого сайт, открывающий форму, меняет свой origin, снимая правила ограничения домена, и пишет свой URL напрямую в форму.
Злоумышленник может создать страничку // evil-bucket.website.yandexcloud.net/ в своём бакете, которая так же меняет заголовок запроса origin, и получить полный доступ к контенту формы логина компании:
<!DOCTYPE html>
<html>
<body>
<h1>evil-bucket<h1><hr>
<div id="login">Login: </div>
<div id="password">Password: </div>
<hr>
<iframe name="auth" src="https://corp-bucket2.website.yandexcloud.net/" onload="setInterval(getCredentials, 1000)" style="width: 100vw; height: 80vh"></iframe>
<script>
document.domain='website.yandexcloud.net';
function getCredentials() {
window.login.innerText = "Login: " + auth.login.value;
window.password.innerText = "Password: " + auth.password.value;
}
</script>
</body>
</html>
Теперь, осталось заманить пользователя на эту страницу, и можно получить его пароль, любезно подставленный браузером в знакомую форму.
Примечание
Поведение разнится от браузера к браузеру — на Firefox 68.0 пример работает без дополнительных действий, а в Chromium 75.0 (и других браузерах на том же движке — Яндекс.Браузер, Chrome и др.) для получения пользовательских паролей нужно вынудить пользователя кликнуть по фрейму с формой логина, что обычно не является проблемой
Но, так как теперь браузер считает website.yandexcloud.net доменом верхнего уровня, то он не позволит ни злоумышленнику поднять свой домен до website.yandexcloud.net, ни компании реализовать такую небезопасную схему.
Что не меняется
Внутри бакета все политики работают как раньше. То есть, можно устанавливать cookie на домены
<your_bucket>.website.yandexcloud.net
<your_bucket>.storage.yandexcloud.net
и всё ещё можно менять origin в рамках своего бакета.
Сроки изменений
Теперь о главном — о сроках сроках принятия изменений в браузере. Изменения на уровне браузеров подтягиваются неравномерно. Для Chromium срок обычно 3-4 месяца, у Firefox список обновляется еженедельно, после чего должно пройти ещё некоторое время до выхода новой версии браузера. Релизные циклы других вендоров оценить сложно. Мы предполагаем, что в течение полугода новый список должен попасть во все актуальные браузеры.
С включением доменов в список публичных суффиксов доступ к вашим данным стал намного безопаснее. Кроме того, в Yandex Object Storage мы обеспечиваем следующие условия безопасности данных пользователей:
- данные размещаются на физических носителях в датацентрах Яндекса, которые являются режимными объектами,
- данные хранятся в зашифрованном виде, так что никто из тех, кто имеет доступ к физическому носителю, не сможет их прочитать,
- по умолчанию доступ к хранилищу осуществляется по протоколу HTTPS.