Предотвратите утечки информации CSRF, XSSI и перекрестного происхождения.
Почему вам следует заботиться об изоляции ваших веб-ресурсов?
Многие веб-приложения уязвимы для атак из разных источников, таких как подделка межсайтовых запросов (CSRF), межсайтовое включение сценариев (XSSI), атаки по времени, утечки информации из разных источников или атаки спекулятивного выполнения по побочному каналу ( Spectre ).
Заголовки запроса на получение метаданных позволяют вам развернуть надежный механизм глубокоэшелонированной защиты — политику изоляции ресурсов — для защиты вашего приложения от этих распространенных атак из разных источников.
Ресурсы, предоставляемые конкретным веб-приложением, обычно загружаются только самим приложением, а не другими веб-сайтами. В таких случаях развертывание политики изоляции ресурсов на основе заголовков запроса на получение метаданных требует особых усилий и в то же время защищает приложение от межсайтовых атак.
Совместимость с браузером
Заголовки запроса Fetch Metadata поддерживаются во всех современных браузерных движках.
Фон
Возможны многие межсайтовые атаки, поскольку сеть по умолчанию открыта, и ваш сервер приложений не может легко защитить себя от связи, исходящей от внешних приложений. Типичной атакой между источниками является подделка межсайтового запроса (CSRF), когда злоумышленник заманивает пользователя на контролируемый им сайт, а затем отправляет форму на сервер, на котором пользователь вошел в систему. Поскольку сервер не может определить, исходил ли запрос из другого домена (межсайтовый), а браузер автоматически присоединяет файлы cookie к межсайтовым запросам, сервер выполнит действие, запрошенное злоумышленником, от имени пользователя.
Другие межсайтовые атаки, такие как межсайтовое включение сценариев (XSSI) или утечки информации из разных источников, по своей природе аналогичны CSRF и основаны на загрузке ресурсов из приложения-жертвы в документ, контролируемый злоумышленником, и утечке информации о приложениях-жертвах. Поскольку приложения не могут легко отличить доверенные запросы от ненадежных, они не могут игнорировать вредоносный межсайтовый трафик.
Представляем выборку метаданных
Заголовки запроса Fetch Metadata — это новая функция безопасности веб-платформы, призванная помочь серверам защититься от атак из разных источников. Предоставляя информацию о контексте HTTP-запроса в наборе заголовков Sec-Fetch-*
, они позволяют отвечающему серверу применять политики безопасности перед обработкой запроса. Это позволяет разработчикам решать, принимать или отклонять запрос в зависимости от того, как он был сделан и контекста, в котором он будет использоваться, что позволяет отвечать только на законные запросы, сделанные их собственным приложением.
Sec-Fetch-Site
Sec-Fetch-Site
сообщает серверу, какой сайт отправил запрос. Браузер устанавливает для этого значения одно из следующих значений:
-
same-origin
, если запрос был сделан вашим собственным приложением (например,site.example
). -
same-site
, если запрос был сделан с поддомена вашего сайта (например,bar.site.example
). -
none
, если запрос был явно вызван взаимодействием пользователя с пользовательским агентом (например, нажатием на закладку) -
cross-site
, если запрос был отправлен с другого сайта (например,evil.example
).
Sec-Fetch-Mode
Sec-Fetch-Mode
указывает режим запроса. Это примерно соответствует типу запроса и позволяет отличить загрузку ресурсов от запросов навигации. Например, пункт назначения navigate
указывает на запрос навигации верхнего уровня, а параметр no-cors
указывает на запросы ресурсов, такие как загрузка изображения.
Sec-Fetch-Dest
Sec-Fetch-Dest
раскрывает место назначения запроса (например, если script
или тег img
вызвал запрос ресурса браузером).
Как использовать Fetch Metadata для защиты от атак из разных источников
Дополнительная информация, которую предоставляют эти заголовки запросов, довольно проста, но дополнительный контекст позволяет вам создать мощную логику безопасности на стороне сервера, также называемую политикой изоляции ресурсов, с помощью всего лишь нескольких строк кода.
Реализация политики изоляции ресурсов
Политика изоляции ресурсов предотвращает запрос ваших ресурсов внешними веб-сайтами. Блокировка такого трафика смягчает распространенные межсайтовые веб-уязвимости, такие как CSRF, XSSI, атаки по времени и утечки информации из разных источников. Эту политику можно включить для всех конечных точек вашего приложения, и она разрешит все запросы ресурсов, поступающие из вашего собственного приложения, а также прямую навигацию (через HTTP-запрос GET
). Конечные точки, которые должны загружаться в межсайтовом контексте (например, конечные точки, загружаемые с использованием CORS), можно отключить от этой логики.
Шаг 1. Разрешите запросы от браузеров, которые не отправляют метаданные Fetch.
Поскольку не все браузеры поддерживают получение метаданных, вам необходимо разрешить запросы, которые не устанавливают заголовки Sec-Fetch-*
, проверив наличие sec-fetch-site
.
if not req['sec-fetch-site']:
return True # Allow this request
Шаг 2. Разрешите запросы, инициируемые одним сайтом и браузером.
Будут разрешены любые запросы, которые не исходят из контекста перекрестного происхождения (например, evil.example
). В частности, это запросы, которые:
- Создайте свое собственное приложение (например, запрос того же источника, где запросы
site.example
site.example/foo.json
всегда будут разрешены). - Происходят из ваших поддоменов.
- Явно вызваны взаимодействием пользователя с пользовательским агентом (например, прямой навигацией или щелчком по закладке и т. д.).
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True # Allow this request
Шаг 3. Разрешите простую навигацию верхнего уровня и iframe.
Чтобы гарантировать, что на ваш сайт по-прежнему можно будет ссылаться с других сайтов, вам необходимо разрешить простую ( HTTP GET
) навигацию верхнего уровня.
if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
# <object> and <embed> send navigation requests, which we disallow.
and req['sec-fetch-dest'] not in ('object', 'embed'):
return True # Allow this request
Шаг 4. Отключите конечные точки, предназначенные для обслуживания межсайтового трафика (необязательно).
В некоторых случаях ваше приложение может предоставлять ресурсы, предназначенные для межсайтовой загрузки. Эти ресурсы необходимо освободить для каждого пути или для каждой конечной точки. Примеры таких конечных точек:
- Конечные точки, предназначенные для доступа из разных источников. Если ваше приложение обслуживает конечные точки с поддержкой
CORS
, вам необходимо явно отключить для них изоляцию ресурсов, чтобы гарантировать, что межсайтовые запросы к этим конечным точкам по-прежнему возможны. - Публичные ресурсы (например, изображения, стили и т. д.). Любые общедоступные и неаутентифицированные ресурсы, которые должны быть доступны для загрузки с других сайтов из разных источников, также могут быть исключены.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
return True
Шаг 5. Отклоните все остальные запросы, которые являются межсайтовыми и не связаны с навигацией.
Любой другой межсайтовый запрос будет отклонен настоящей Политикой изоляции ресурсов и, таким образом, защитит ваше приложение от распространенных межсайтовых атак.
Пример. Следующий код демонстрирует полную реализацию надежной политики изоляции ресурсов на сервере или в качестве промежуточного программного обеспечения для отклонения потенциально вредоносных межсайтовых запросов на ресурсы, одновременно разрешая простые навигационные запросы:
# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
# Allow requests from browsers which don't send Fetch Metadata
if not req['sec-fetch-site']:
return True
# Allow same-site and browser-initiated requests
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True
# Allow simple top-level navigations except <object> and <embed>
if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
and req['sec-fetch-dest'] not in ('object', 'embed'):
return True
# [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
return True
# Reject all other requests that are cross-site and not navigational
return False
Развертывание политики изоляции ресурсов
- Установите модуль, подобный приведенному выше фрагменту кода, чтобы регистрировать и отслеживать поведение вашего сайта, а также убедиться, что ограничения не влияют на законный трафик.
- Устраните потенциальные нарушения, исключив законные конечные точки с перекрестным происхождением.
- Обеспечьте соблюдение политики, отклоняя несоответствующие запросы.
Выявление и устранение нарушений политики
Рекомендуется протестировать политику без побочных эффектов, сначала включив ее в режиме отчетов в серверном коде. Альтернативно вы можете реализовать эту логику в промежуточном программном обеспечении или в обратном прокси-сервере, который регистрирует любые нарушения, которые ваша политика может вызвать при применении к рабочему трафику.
Судя по нашему опыту внедрения политики изоляции ресурсов метаданных при извлечении данных в Google, большинство приложений по умолчанию совместимы с такой политикой и редко требуют исключения конечных точек для разрешения межсайтового трафика.
Применение политики изоляции ресурсов
Убедившись, что ваша политика не влияет на законный производственный трафик, вы готовы применять ограничения, гарантируя, что другие сайты не смогут запрашивать ваши ресурсы, и защищая ваших пользователей от межсайтовых атак.
Дальнейшее чтение
- Спецификация заголовков запроса на получение метаданных W3C
- Получить метаданные
- Доклад Google I/O: защита веб-приложений с помощью современных функций платформы (слайды)