Доступ к частной сети: предварительная проверка

Титуан Ригуди
Titouan Rigoudy
Ифань Ло
Yifan Luo

Обновления

  • 7 июля 2022 г .: обновлен текущий статус и добавлено определение пространства IP-адресов.
  • 27 апреля 2022 г .: Объявление об обновлении графика.
  • 7 марта 2022 г .: Объявлено об откате после обнаружения проблем в Chrome 98.

Введение

Chrome прекращает поддержку прямого доступа к конечным точкам частной сети с общедоступных веб-сайтов в рамках спецификации Private Network Access (PNA).

Chrome начнет отправлять предварительный запрос CORS перед любым запросом частной сети для подресурса, который запрашивает явное разрешение от целевого сервера. Этот предварительный запрос будет содержать новый заголовок Access-Control-Request-Private-Network: true , а ответ на него должен содержать соответствующий заголовок Access-Control-Allow-Private-Network: true .

Целью является защита пользователей от атак с подделкой межсайтовых запросов (CSRF), нацеленных на маршрутизаторы и другие устройства в частных сетях. Эти атаки затронули сотни тысяч пользователей , позволяя злоумышленникам перенаправлять их на вредоносные серверы.

План внедрения

Chrome внедрит это изменение в два этапа, чтобы дать веб-сайтам время заметить изменение и внести соответствующие изменения.

  1. В Chrome 104:

    • Chrome экспериментирует, отправляя предварительные запросы перед запросами подресурсов частной сети.
    • Ошибки предварительной проверки только отображают предупреждения в DevTools, не влияя иным образом на запросы частной сети.
    • Chrome собирает данные о совместимости и обращается к крупнейшим затронутым веб-сайтам.
    • Мы ожидаем, что это будет в целом совместимо с существующими веб-сайтами.
  2. Не ранее Chrome 113:

    • Это произойдет только в том случае, если данные о совместимости покажут, что изменение достаточно безопасно, и мы свяжемся с вами напрямую при необходимости.
    • Chrome требует, чтобы предварительные запросы были выполнены успешно, в противном случае запросы отклоняются.
    • В то же время начинается пробный период устаревания , позволяющий веб-сайтам, затронутым этой фазой, запросить продление времени. Пробный период продлится не менее 6 месяцев.

Что такое доступ к частной сети (PNA)

Доступ к частной сети (ранее известный как CORS-RFC1918 ) ограничивает возможность веб-сайтов отправлять запросы серверам в частных сетях.

Chrome уже реализовал часть спецификации: начиная с Chrome 96, только безопасные контексты могут делать запросы частной сети. Подробности см. в нашем предыдущем сообщении в блоге .

Спецификация также расширяет протокол Cross-Origin Resource Sharing (CORS), так что теперь веб-сайты должны явно запрашивать грант у серверов в частных сетях, прежде чем им будет разрешено отправлять произвольные запросы.

Как PNA классифицирует IP-адреса и идентифицирует частную сеть

IP-адреса классифицируются по трем пространствам IP-адресов: - public - private - local

Локальное пространство IP-адресов содержит IP-адреса, которые являются либо петлевыми адресами IPv4 ( 127.0.0.0/8 ), определенными в разделе 3.2.1.3 RFC1122 , либо петлевыми адресами IPv6 ( ::1/128 ), определенными в разделе 2.5.3 RFC4291 .

Пространство частных IP-адресов содержит IP-адреса, имеющие значение только в пределах текущей сети, включая 10.0.0.0/8 , 172.16.0.0/12 и 192.168.0.0/16 определенные в RFC1918 , локальные адреса связи 169.254.0.0/16 определенные в RFC3927 , уникальные локальные адреса индивидуальной рассылки IPv6 fc00::/7 , определенные в RFC4193 , локальные адреса индивидуальной рассылки IPv6 fe80::/10 определенные в разделе 2.5.6 RFC4291 , и сопоставленные с IPv4 адреса IPv6, где сопоставленный адрес IPv4 сам по себе является частным.

Пространство публичных IP-адресов содержит все остальные адреса, не упомянутые ранее.

Локальный IP-адрес считается более конфиденциальным, чем частный IP-адрес, который, в свою очередь, считается более конфиденциальным, чем публичный IP-адрес.

Запросы являются частными, когда более доступная сеть отправляет запрос в менее доступную сеть.
Взаимосвязь между публичными, частными и локальными сетями в доступе к частным сетям (CORS-RFC1918)

Узнайте больше на странице Требуются отзывы: CORS для частных сетей (RFC1918) .

Предварительные запросы

Фон

Запросы Preflight — это механизм, введенный стандартом Cross-Origin Resource Sharing (CORS), который используется для запроса разрешения у целевого веб-сайта перед отправкой ему HTTP-запроса, который может иметь побочные эффекты. Это гарантирует, что целевой сервер понимает протокол CORS, и значительно снижает риск CSRF-атак.

Запрос на разрешение отправляется как HTTP-запрос OPTIONS с определенными заголовками запроса CORS, описывающими предстоящий HTTP-запрос. Ответ должен содержать определенные заголовки ответа CORS, явно соглашающиеся с предстоящим запросом.

Диаграмма последовательности, представляющая предварительный просмотр CORS. Запрос OPTIONS HTTP отправляется на цель, которая возвращает 200 OK. Затем отправляется заголовок запроса CORS, возвращающий заголовок ответа CORS

Что нового в доступе к частной сети

Для предварительных запросов введена новая пара заголовков запроса и ответа:

  • Access-Control-Request-Private-Network: true устанавливается для всех предварительных запросов PNA
  • Access-Control-Allow-Private-Network: true

Предварительные запросы для PNA отправляются для всех запросов частной сети, независимо от метода и режима запроса. Они отправляются перед запросами в режиме cors , а также no-cors и всех других режимах. Это связано с тем, что все запросы частной сети могут использоваться для атак CSRF, независимо от режима запроса и от того, доступно ли содержимое ответа инициатору.

Предварительные запросы для PNA также отправляются для запросов с тем же происхождением, если целевой IP-адрес более приватный, чем инициатор. Это отличается от обычного CORS, где предварительные запросы предназначены только для запросов с перекрестным происхождением. Предварительные запросы для запросов с тем же происхождением защищают от атак перепривязки DNS .

Примеры

Наблюдаемое поведение зависит от режима запроса .

Режим No-CORS

Допустим https://foo.example/index.html встраивает <img src="https://bar.example/cat.gif" alt="dancing cat"/> , а bar.example преобразуется в 192.168.1.1 , частный IP-адрес согласно RFC 1918 .

Сначала Chrome отправляет предварительный запрос:

HTTP/1.1 OPTIONS /cat.gif
Origin: https://foo.example
Access-Control-Request-Private-Network: true

Для успешного выполнения этого запроса сервер должен ответить:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Private-Network: true

Затем Chrome отправит сам запрос:

HTTP/1.1 GET /cat.gif
...

На которые сервер может нормально ответить.

режим CORS

Допустим, https://foo.example/index.html запускает следующий код:

await fetch('https://bar.example/delete-everything', {
  method: 'PUT',
  credentials: 'include',
})

Опять же, предположим, что bar.example разрешается в 192.168.1.1 .

Сначала Chrome отправляет предварительный запрос:

HTTP/1.1 OPTIONS /delete-everything
Origin: https://foo.example
Access-Control-Request-Method: PUT
Access-Control-Request-Credentials: true
Access-Control-Request-Private-Network: true

Для успешного выполнения этого запроса сервер должен ответить:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://foo.example
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Credentials: true
Access-Control-Allow-Private-Network: true

Затем Chrome отправит сам запрос:

HTTP/1.1 PUT /delete-everything
Origin: https://foo.example

На что сервер может ответить в соответствии с обычными правилами CORS:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://foo.example

Как узнать, затронут ли ваш сайт

Начиная с Chrome 104, если обнаружен запрос частной сети, перед ним будет отправлен предварительный запрос. Если этот предварительный запрос не будет выполнен, окончательный запрос все равно будет отправлен, но на панели проблем DevTools появится предупреждение.

Предупреждение о неудачном предварительном запросе на панели проблем Devtools. В нем говорится: убедитесь, что запросы частной сети выполняются только к тем ресурсам, которые это разрешают, а также сведения о конкретном запросе и перечисленные затронутые ресурсы.

Затронутые предварительные запросы также можно просмотреть и диагностировать на сетевой панели:

Неудачный предварительный запрос в панели DevTools Network для localhost дает статус 501.

Если ваш запрос вызвал бы обычный предварительный запуск CORS без правил доступа к частной сети, то на сетевой панели могут появиться два предварительных запуска, причем первый всегда будет выглядеть неудачным. Это известная ошибка , и вы можете смело ее игнорировать.

Ложный неудачный предварительный запрос перед успешным предварительным проверкой на панели DevTools Network.

Чтобы просмотреть, что произойдет, если предварительная проверка прошла успешно, можно передать следующий аргумент командной строки , начиная с Chrome 98:

--enable-features=PrivateNetworkAccessRespectPreflightResults

Любой неудачный предварительный запрос приведет к неудачной выборке. Это позволит вам проверить, будет ли работать ваш веб-сайт после второй фазы нашего плана развертывания . Ошибки можно диагностировать так же, как и предупреждения, с помощью панелей DevTools, упомянутых выше.

Что делать, если ваш сайт пострадал

Когда это изменение будет реализовано в Chrome 104, оно не должно нарушить работу какого-либо веб-сайта. Однако мы настоятельно рекомендуем вам обновить затронутые пути запросов, чтобы гарантировать, что ваш веб-сайт продолжит работать так, как и ожидалось.

Вам доступны два решения:

  1. Обработка предварительных запросов на стороне сервера
  2. Отключить проверки PNA с помощью корпоративных политик

Обработка предварительных запросов на стороне сервера

Обновите целевой сервер всех затронутых выборок для обработки предварительных запросов PNA. Сначала реализуйте поддержку стандартных предварительных запросов CORS на затронутых маршрутах. Затем добавьте поддержку двух новых заголовков ответов .

Когда ваш сервер получает предварительный запрос (запрос OPTIONS с заголовками CORS), сервер должен проверить наличие заголовка Access-Control-Request-Private-Network: true . Если этот заголовок присутствует в запросе, сервер должен проверить заголовок Origin и путь запроса вместе с любой другой соответствующей информацией (например, Access-Control-Request-Headers ), чтобы убедиться, что запрос безопасен для разрешения. Обычно вы должны разрешить доступ к одному источнику под вашим контролем.

Как только ваш сервер решил разрешить запрос, он должен ответить 204 No Content (или 200 OK ) с необходимыми заголовками CORS и новым заголовком PNA. Эти заголовки включают Access-Control-Allow-Origin и Access-Control-Allow-Private-Network: true , а также другие по мере необходимости.

Конкретные сценарии смотрите в примерах .

Отключите проверки доступа к частной сети с помощью корпоративных политик

Если у вас есть административный контроль над вашими пользователями, вы можете отключить проверки доступа к частной сети, используя любую из следующих политик:

Для получения дополнительной информации обратитесь к разделу Общие сведения об управлении политиками Chrome .

Оставьте нам отзыв

Если вы размещаете веб-сайт в частной сети, которая ожидает запросы из публичных сетей, команда Chrome заинтересована в ваших отзывах и вариантах использования. Дайте нам знать, отправив сообщение о проблеме с Chromium на crbug.com и задайте компоненту Blink>SecurityFeature>CORS>PrivateNetworkAccess .

Что дальше?

Далее Chrome расширит проверки доступа к частной сети, чтобы охватить веб-воркеров : выделенных воркеров, общих воркеров и воркеров сервисов. Мы ориентируемся на Chrome 107, чтобы начать показывать предупреждения.

Затем Chrome расширит проверки доступа к частной сети, чтобы охватить навигации, включая iframes и всплывающие окна. Мы ориентируемся на Chrome 108, чтобы начать показывать предупреждения.

В обоих случаях мы будем действовать осторожно, применяя аналогичное поэтапное развертывание, чтобы дать веб-разработчикам время на корректировку и оценку риска совместимости.

Благодарности

Фотография на обложке сделана Марком Олсеном на Unsplash .