Управляйте доступом вашей страницы и сторонних фреймов на ней к функциям браузера.
Политика разрешений (Permissions Policy), ранее известная как политика функций (Feature Policy), позволяет разработчику контролировать функции браузера, доступные для страницы, её фреймов (iframe) и подресурсов, декларируя набор политик, которые браузер будет применять. Эти политики применяются к источникам, указанным в списке источников в заголовке ответа. Список источников может содержать как те же источники, так и кросс-источники, и позволяет разработчику контролировать доступ как основных, так и сторонних пользователей к функциям браузера.
Пользователь принимает окончательное решение о предоставлении доступа к более мощным функциям и должен предоставить явное разрешение, приняв запрос.
Политика разрешений позволяет сайту верхнего уровня определять, что он и его третьи стороны намерены использовать, и снимает с пользователя бремя проверки законности запроса на доступ к функции. Например, блокируя функцию геолокации для всех третьих сторон с помощью политики разрешений, разработчик может быть уверен, что никакая третья сторона не получит доступ к геолокации пользователя.
Изменения в политике разрешений
Политика разрешений ранее называлась Политикой функций. Основные концепции остались прежними, но помимо названия произошли и некоторые важные изменения.
Использование структурированных полей
Структурированные поля предоставляют набор распространённых структур данных для стандартизации анализа и сериализации значений полей HTTP-заголовков. Подробнее о структурированных полях можно узнать в статье блога Fastly « Улучшение HTTP с помощью структурированных полей заголовков ».
geolocation 'self' https://example.com; camera 'none'
До с Политикой функций.
geolocation=(self "https://example.com"), camera=()
Теперь с политикой разрешений.
Объедините заголовки с атрибутом allow
iframe
С помощью политики функций вы можете добавить функцию во фрейм с кросс-источниками, добавив источник в список источников заголовка или атрибут allow
в тег iframe. С помощью политики разрешений, если вы добавляете фрейм с кросс-источниками в список источников, тег iframe для этого источника должен включать атрибут allow
. Если ответ не содержит заголовка политики разрешений, считается, что список источников имеет значение по умолчанию *
. Добавление атрибута allow
в тег iframe разрешает доступ к функции.
Поэтому мы рекомендуем разработчикам явно указывать заголовок «Политика разрешений» в ответе, чтобы кросс-источниковые iframe, не указанные в списке источников, не имели доступа к этой функции, даже если присутствует allow
.
Feature Policy можно использовать и после Chrome 88, но он действует как псевдоним для Permissions Policy. За исключением синтаксиса, логика ничем не отличается. Если оба заголовка Permissions Policy и Feature Policy используются одновременно, заголовок Permissions-Policy
будет иметь более высокий приоритет и перезапишет значение, предоставленное заголовком Feature-Policy
.
Как использовать политику разрешений?
Краткий обзор
Прежде чем углубляться в детали, кратко рассмотрим распространенный сценарий, когда вы являетесь владельцем веб-сайта и хотите контролировать, как ваш сайт и сторонний код используют функции браузера.
- Ваш сайт —
https://your-site.example
. - На вашем сайте встроен iframe из того же источника (
https://your-site.example
). - На вашем сайте встроен iframe из
https://trusted-site.example
которому вы доверяете. - На вашем сайте также отображаются объявления, обслуживаемые
https://ad.example
. - Вы хотите разрешить геолокацию только для своего сайта и доверенного сайта, а не для рекламы.
В этом случае используйте следующий заголовок:
Permissions-Policy: geolocation=(self "https://trusted-site.example")
И явно задайте атрибут allow
для тега iframe для доверенного сайта:
<iframe src="https://trusted-site.example" allow="geolocation">
В этом примере список источников заголовков позволяет использовать функцию геолокации только вашему сайту ( self
) и trusted-site.example
. ad.example
не имеет права использовать геолокацию.
- Вашему сайту
your-site.example
разрешено использовать функцию геолокации с согласия пользователя. - Для iframe того же источника (
your-site.example
) разрешено использовать эту функцию без использования атрибутаallow
. - iframe, размещенный с другого поддомена (
subdomain.your-site-example
), который не был добавлен в список источников и имеет атрибут allow в теге iframe, блокирует использование этой функции. Разные поддомены считаются принадлежащими одному сайту, но кросс-доменными. - Кросс-источник iframe (
trusted-site.example
), добавленный в список источников и имеющий атрибутallow
установленный в теге iframe, может использовать эту функцию. - Кросс-источниковый iframe (
trusted-site.example
), добавленный в список источников без атрибутаallow
, блокирует использование этой функции. - Кросс-источниковый iframe (
ad.example
), который не был добавлен в список источников, блокирует использование этой функции, даже если атрибутallow
включен в тег iframe.
Заголовок ответа HTTP Permissions-Policy
Permissions-Policy: <feature>=(<token>|<origin(s)>)
Используйте заголовок Permissions-Policy
в ответе сервера, чтобы задать разрешённые источники для функции. Значение заголовка может содержать комбинацию токенов и строк источников. Доступные токены : *
для всех источников и self
для одного и того же источника.
Если заголовок предназначен для нескольких функций, разделяйте их запятыми. Если вы перечисляете несколько источников, разделяйте каждый источник в списке пробелом. Для заголовков, в которых указан источник, являющийся запросом кросс-источника, тег iframe должен включать атрибут allow
.
Вот несколько примеров пар «ключ-значение»:
- Синтаксис:
[FEATURE]=*
- Политика применяется ко всем источникам
- Пример:
geolocation=*
- Синтаксис:
[FEATURE]=(self)
- Политика применяется к тому же происхождению
- Пример:
geolocation=(self)
- Синтаксис:
[FEATURE]=(self [ORIGIN(s)])
- Политика применяется к одному и тому же источнику и указанным источникам
- Пример:
geolocation=(self "https://a.example" "https://b.example")
-
self
— это сокращение отhttps://your-site.example
- Синтаксис:
[FEATURE]=([ORIGIN(s)])
- Политика применяется к одному и тому же источнику и указанным источникам
- Пример:
geolocation=("https://your-site.example" "https://a.example" "https://b.example")
- При использовании этого синтаксиса одним из источников должен быть источник встраиваемого приложения. Если самой странице встраиваемого приложения не предоставлены разрешения, встроенные на этой странице iframe также будут заблокированы, даже если они добавлены в список источников, поскольку политика разрешений делегирует разрешения. Вы также можете использовать токен
self
.
- Синтаксис:
[FEATURE]=()
- Функция заблокирована для всех источников
- Пример:
geolocation=()
Различные поддомены и пути
Разные поддомены, такие как https://your-site.example
и https://subdomain.your-site.example
, считаются поддоменами одного и того же сайта, но с кросс-доменом . Поэтому добавление поддомена в список источников не разрешает доступ к другому поддомену того же сайта. Каждый встроенный поддомен, который хочет использовать эту функцию, должен быть добавлен в список источников отдельно. Например, если доступ к темам просмотра пользователя разрешен только для того же источника с заголовком Permissions-Policy: browsing-topics=(self)
, iframe из другого поддомена того же сайта, https://subdomain.your-site.example
, не будет иметь доступа к этим темам.
Различные пути, такие как https://your-site.example
и https://your-site.example/embed
, считаются принадлежащими одному и тому же источнику, и различные пути не обязательно должны быть указаны в списке источников.
Атрибут allow
iframe
Для использования в разных источниках iframe должен иметь атрибут allow
в теге, чтобы получить доступ к функции.
Синтаксис: <iframe src="[ORIGIN]" allow="[FEATURE] <'src' | [ORIGIN(s)]"></iframe>
Например:
<iframe src="https://trusted-site.example" allow="geolocation">
Управление навигацией iframe
По умолчанию, если iframe переходит в другой источник, политика не применяется к источнику, к которому переходит iframe. Если указать источник, к которому переходит iframe, в атрибуте allow
, политика разрешений, примененная к исходному iframe, будет применена к источнику, к которому переходит iframe.
<iframe src="https://trusted-site.example" allow="geolocation https://trusted-site.example https://trusted-navigated-site.example">
Вы можете увидеть это в действии, посетив демонстрационную версию навигации iframe .
Примеры настроек политики разрешений
Примеры следующих настроек можно найти в демо-версии .
Функция разрешена для всех источников
Permissions-Policy: geolocation=*
<iframe src="https://trusted-site.example" allow="geolocation">
<iframe src="https://ad.example" allow="geolocation">
Если в списке источников задан токен *
, функция разрешена для всех источников на странице, включая саму страницу и все iframe. В этом примере весь код, передаваемый с https://your-site.example
, а также коды, передаваемые с https://trusted-site.example
iframe и https://ad.example
имеют доступ к функции геолокации в браузере пользователя. Помните, что атрибут allow также должен быть установлен для самого iframe вместе с добавлением источника в список источников заголовка.
Эту настройку можно увидеть в демо-версии .
Функция разрешена только в том же источнике
Permissions-Policy: geolocation=(self)
Использование токена self
позволяет использовать геолокацию только для одного и того же источника. Доступ к этой функции будет закрыт для пользователей из разных источников. В этом примере доступ к геолокации будет только у https://trusted-site.example
( self
). Используйте этот синтаксис, если хотите, чтобы эта функция была доступна только для вашей страницы и ни для кого другого.
Эту настройку можно увидеть в демо-версии .
Функция разрешена для одного и того же источника и определенных перекрестных источников
Permissions-Policy: geolocation=(self "https://trusted-site.example")
Этот синтаксис позволяет использовать геолокацию как для себя ( https://your-site.example
), так и для https://trusted-site.example
. Не забудьте явно добавить атрибут allow в тег iframe. Если есть другой iframe с <iframe src="https://ad.example" allow="geolocation">
, то у https://ad.example
не будет доступа к функции геолокации. Доступ к функции пользователя будет иметь только исходная страница и https://trusted-site.example
, указанный в списке источников и имеющий атрибут allow в теге iframe.
Эту настройку можно увидеть в демо-версии .
Функция заблокирована для всех источников
Permissions-Policy: geolocation=()
При пустом списке источников эта функция блокируется для всех источников. Эту настройку можно увидеть в демо-версии .
Используйте JavaScript API
Существующий JavaScript API для Feature Policy представлен как объект в документе или элементе ( document.featurePolicy or element.featurePolicy
). JavaScript API для Permissions Policy пока не реализован.
API политики функций можно использовать для политик, установленных политикой разрешений, с некоторыми ограничениями. Остались вопросы по реализации JavaScript API, и было предложено перенести логику в API разрешений . Присоединяйтесь к обсуждению, если у вас есть какие-либо идеи.
featurePolicy.allowsFeature(feature)
- Возвращает значение
true
, если функция разрешена для использования в источнике по умолчанию. - Поведение одинаково для обеих политик, установленных политикой разрешений и предыдущей политикой функций.
- Когда
allowsFeature()
вызывается для элемента iframe (iframeEl.featurePolicy.allowsFeature('geolocation')
), возвращаемое значение отражает, установлен ли атрибут allow для iframe
featurePolicy.allowsFeature(feature, origin)
- Возвращает значение
true
, если функция разрешена для указанного источника. - Если метод вызывается для
document
, он больше не сообщает, разрешена ли функция для указанного источника, как это делал Feature Policy. Теперь этот метод сообщает, что функция может быть разрешена для этого источника. Необходимо провести дополнительную проверку того, установлен ли атрибутallow
для элемента iframe. Разработчик должен провести дополнительную проверку атрибутаallow
для элемента iframe, чтобы определить, разрешена ли функция для стороннего источника.
Проверьте наличие функций в iframe с помощью объекта element
Вы можете использовать element.allowsFeature(feature)
, который учитывает атрибут allow, в отличие от document.allowsFeature(feature, origin)
, который этого не делает.
const someIframeEl = document.getElementById('some-iframe')
const isCameraFeatureAllowed = someIframeEl.featurePolicy.allowsFeature('camera')
featurePolicy.allowedFeatures()
- Возвращает список функций, разрешенных для использования в источнике по умолчанию.
- Поведение одинаково для обеих политик, установленных политикой разрешений и политикой функций.
- Если связанный узел является iframe, учитывается атрибут allow.
featurePolicy.features()
- Возвращает список функций, доступных в браузере.
- Поведение одинаково для обеих политик, установленных политикой разрешений и политикой функций.
Интеграция с Chrome DevTools
Узнайте, как работает политика разрешений в DevTools.
- Откройте Chrome DevTools .
- Откройте панель приложений , чтобы проверить разрешенные и запрещенные функции каждого кадра.
- На боковой панели выберите фрейм, который вы хотите проверить. Вам будет представлен список функций, которые разрешено использовать выбранному фрейму, и список функций, которые заблокированы в этом фрейме.
Миграция из Feature-Policy
Если вы используете заголовок Feature-Policy
, вы можете выполнить следующие шаги для перехода на политику разрешений.
Заменить заголовки политики функций на заголовки политики разрешений
Поскольку заголовки Feature Policy поддерживаются только в браузерах на базе Chromium, а заголовки Permissions Policy поддерживаются с Chrome 88 , можно безопасно обновить существующие заголовки с помощью Permissions Policy.
Feature-Policy: autoplay *; geolocation 'self'; camera 'self' 'https://trusted-site.example'; fullscreen 'none';
До с Политикой функций.
Permissions-Policy: autoplay=*, geolocation=(self), camera=(self "https://trusted-site.example"), fullscreen=()
Теперь с политикой разрешений.
Обновить использование document.allowsFeature(feature, origin)
Если вы используете метод document.allowsFeature(feature, origin)
для проверки разрешённых функций для iframe, используйте метод allowsFeature(feature)
прикреплённый к элементу iframe, а не к содержащему document
. Метод element.allowsFeature(feature)
учитывает атрибут allow, а document.allowsFeature(feature, origin)
нет.
Проверить доступ к функциям с помощью document
Чтобы продолжить использовать document
в качестве базового узла, необходимо провести дополнительную проверку атрибута allow
в теге iframe.
<iframe id="some-iframe" src="https://example.com" allow="camera"></iframe>
Permissions-Policy: camera=(self "https://example.com")
const isCameraPolicySet = document.featurePolicy.allowsFeature('camera', 'https://example.com')
const someIframeEl = document.getElementById('some-iframe')
const hasCameraAttributeValue = someIframeEl.hasAttribute('allow')
&& someIframeEl.getAttribute('allow').includes('camera')
const isCameraFeatureAllowed = isCameraPolicySet && hasCameraAttributeValue
Вместо обновления существующего кода с помощью document
рекомендуется вызвать allowsFeature()
для объекта element
, как в предыдущем примере.
API отчетности
API отчетности обеспечивает механизм отчетности для веб-приложений согласованным образом, а API отчетности о нарушениях политики разрешений доступен в качестве экспериментальной функции.
Если вы хотите протестировать экспериментальную функцию, следуйте пошаговому руководству и включите флаг в chrome://flags/#enable-experimental-web-platform-features
. Если флаг включён, вы сможете отслеживать нарушения политики разрешений в DevTools на вкладке «Приложение»:
В следующем примере показано, как может быть построен заголовок API отчетов:
Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"
Content-Security-Policy: script-src 'self'; object-src 'none'; report-to main-endpoint;
Document-Policy: document-write=?0; report-to=main-endpoint;
В текущей реализации вы можете получать отчёты о нарушениях политики, возникающих в пределах данного фрейма, настроив конечную точку с именем «default», как в предыдущем примере. Для подфреймов потребуется собственная конфигурация отчётности.
Узнать больше
Для более глубокого понимания политики разрешений обратитесь к следующим ресурсам: