Privacy & Security

Что на самом деле может заблокировать заголовок Permissions-Policy

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

The Wux Webtools Team The Wux Webtools Team 2 минуты чтения С поддержкой ИИ, проверено человеком
A browser interface with feature toggles limiting access for a page and embedded frames.
Содержание
  1. Краткая версия
  2. Что контролирует Permissions-Policy
  3. Что он может заблокировать на ваших собственных страницах
  4. Что он может заблокировать в iframes
  5. Что он не может заблокировать
  6. Разумная политика по умолчанию
  7. Как внедрить без поломок
  8. 1. Проведите инвентаризацию использования функций
  9. 2. Начните в среде с низким риском
  10. 3. Используйте постраничные policies там, где это необходимо
  11. 4. Проверьте реальный ответ
  12. 5. Документируйте исключения
  13. Распространенные синтаксические ошибки
  14. Практическая ценность для приватности

Краткая версия

Permissions-Policy — это HTTP-заголовок ответа, который позволяет сайту ограничивать доступ к определенным функциям браузера: камере, микрофону, геолокации, полноэкранному режиму, платежам, датчикам и длинному списку менее крупных API.

Это не универсальный щит для приватности. Он не остановит весь трекинг, не заблокирует cookies, не предотвратит сетевые запросы и не сделает сторонний JavaScript безопасным. Но он хорошо справляется с более узкой и все же ценной задачей: сокращает возможности браузера, доступные вашим собственным страницам и встроенным frames.

Это важно, потому что современные сайты собираются из фрагментов аналитики, media embeds, chat widgets, consent managers, рекламных скриптов, карт, платежных сценариев и внутренних экспериментов. Большинству этих компонентов не нужен доступ к мощным API устройства. Хорошая политика делает это явным.

Если вы уже проверяете заголовки в production, сочетайте эту работу с прямой проверкой фактического ответа. В нашем руководстве по отладке redirects и HTTP headers in production описана привычка, которая здесь особенно важна: проверять, что браузер действительно получает, а не то, что, согласно конфигурационному файлу, должно происходить.

Что контролирует Permissions-Policy

Заголовок управляет доступом к именованным функциям браузера. Точный список со временем меняется, потому что меняются браузерные API, но среди распространенных directives есть:

  • camera
  • microphone
  • geolocation
  • fullscreen
  • payment
  • usb
  • bluetooth
  • accelerometer
  • gyroscope
  • magnetometer
  • screen-wake-lock
  • clipboard-read
  • clipboard-write
  • publickey-credentials-get
  • interest-cohort в более старых обсуждениях, сейчас в основном исторический пункт

Directive может разрешать функцию никому, текущему origin или выбранным origins. Например:

Permissions-Policy: camera=(), microphone=(), geolocation=(self)

Это означает, что камера и микрофон отключены для документа и его вложенных browsing contexts, а геолокация разрешена только для того же origin.

Более разрешающий пример:

Permissions-Policy: geolocation=(self "https://maps.example"), fullscreen=(self "https://video.example")

Он разрешает вашему собственному origin и одному указанному поставщику карт использовать геолокацию, а вашему собственному origin и видеопоставщику — запрашивать полноэкранный режим.

Политику оценивает браузер. Если функция запрещена, JavaScript, использующий этот API, должен завершиться ошибкой или вести себя так, будто функция недоступна. Конкретный режим отказа зависит от API. Иногда promise отклоняется. Иногда возможность просто не выглядит пригодной к использованию.

Что он может заблокировать на ваших собственных страницах

На first-party страницах Permissions-Policy наиболее полезен как ограничитель. Он снижает радиус поражения от случайного или неожиданного кода.

Например, marketing page, скорее всего, не нужны микрофон, камера, Bluetooth, USB, датчики движения или платежные API. Эти функции можно запретить глобально:

Permissions-Policy: camera=(), microphone=(), bluetooth=(), usb=(), payment=(), accelerometer=(), gyroscope=(), magnetometer=()

Это не делает каждый скрипт на странице надежным. Но это означает, что если эксперимент в tag manager, скомпрометированная зависимость или вставленный widget попытается вызвать ограниченный API, браузер не должен предоставить ему доступ.

Для команд с большим числом участников это полезное значение по умолчанию. Оно переводит разговор от расплывчатого доверия к явным возможностям. Если будущей функции действительно понадобится камера, кому-то придется изменить политику и объяснить почему.

Это правильный вид трения.

Что он может заблокировать в iframes

Заголовок становится особенно полезен вокруг встроенного контента.

Браузеры уже рассматривают iframes как отдельные browsing contexts, но встроенный сторонний контент все равно может запрашивать мощные функции, если это разрешено policy и iframe attributes. Permissions-Policy позволяет родительской странице задать верхнюю границу.

Например, если ваша страница встраивает video player, support widget и карту, можно не давать каждому frame доступ ко всем функциям. Вы можете разрешить полноэкранный режим только для video frame, а геолокацию — только для map frame.

Нужно понимать два уровня:

  1. HTTP-заголовок Permissions-Policy задает policy для документа.
  2. Атрибут iframe allow может делегировать frame определенные функции, но только в пределах того, что разрешает parent policy.

Простой iframe может выглядеть так:

<iframe src="https://video.example/embed/123" allow="fullscreen"></iframe>

Если ваш заголовок полностью запрещает fullscreen, атрибут iframe не может переопределить этот запрет. Если заголовок разрешает fullscreen для этого origin, атрибут iframe может делегировать его.

Эта иерархия — одна из причин использовать заголовок. Он дает platform или security teams способ задавать границы для всего сайта, при этом позволяя product teams включать конкретные embeds там, где это нужно.

Что он не может заблокировать

Именно здесь команды иногда переоценивают заголовок.

Permissions-Policy не заменяет content security policy. Он не решает, какие скрипты могут загружаться. Он не мешает скрипту отправлять данные по сети. Он не очищает HTML. Он не предотвращает XSS. Он не блокирует form spam. Если проблема в злоупотреблении формами, начните с механики, описанной в статье why your contact form is your biggest spam liability, а не с этого заголовка.

Он также не заменяет управление cookies. Cookies, local storage, consent, сторонние embeds и браузерные protections от трекинга — это отдельные вопросы. Если вы широко пересматриваете privacy controls, cookie landscape заслуживает отдельного прохода; практические изменения разобраны в what changed for cookies in 2026 and what to do about it.

Самое главное: Permissions-Policy не делает сторонний JavaScript приватным. Если вы загружаете сторонний скрипт на first-party страницу, он обычно выполняется с привилегиями вашей страницы, с учетом других ограничений браузера и ваших security headers. Запрет доступа к камере — это хорошо. Но он не мешает такому скрипту читать содержимое DOM, наблюдать действия пользователя или выполнять разрешенные сетевые запросы.

Для этого нужны другие меры: тщательный выбор vendors, CSP, sandboxed iframes, Subresource Integrity там, где применимо, минимизация данных и скучные, но необходимые проверки.

Разумная политика по умолчанию

Универсального заголовка, подходящего каждому сайту, не существует, но большинство content и marketing sites могут начать с ограничительного варианта.

Разумная первая версия:

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), bluetooth=(), accelerometer=(), gyroscope=(), magnetometer=(), screen-wake-lock=()

Затем возвращайте только то, что сайт действительно использует.

Например:

  • Магазину, использующему Payment Request API, может понадобиться payment=(self).
  • Сервису поиска локаций может понадобиться geolocation=(self) или доверенный map origin.
  • Приложению для конференций могут понадобиться camera=(self) и microphone=(self).
  • Сайту с большим количеством видео может понадобиться fullscreen=(self "https://trusted-video.example").

Важно не скопировать огромную policy из checklist и считать работу завершенной. Начните с инвентаризации функций. Каким страницам нужны какие возможности браузера? Каким embeds нужно делегирование? Запрос каких функций выглядел бы неожиданно?

Как внедрить без поломок

Разворачивайте это как любой другой production header: осознанно.

1. Проведите инвентаризацию использования функций

Поищите в codebase вызовы браузерных API, такие как getUserMedia, geolocation, requestFullscreen, PaymentRequest, Web Bluetooth, WebUSB и wake lock APIs.

Затем проверьте сторонние embeds. В документации video, maps, payment и identity providers часто указываются необходимые значения iframe allow.

2. Начните в среде с низким риском

Добавьте ограничительный заголовок в staging и протестируйте основные user journeys. Обращайте внимание на сообщения в browser console. Браузеры часто сообщают, когда функция заблокирована permissions policy.

3. Используйте постраничные policies там, где это необходимо

Не навязывайте одну глобальную policy, если в продукте есть очень разные типы страниц. Blog, checkout, map page и video room, скорее всего, требуют разных возможностей.

Большинство web servers, frameworks и edge platforms могут устанавливать headers условно по path. Часто это чище, чем ослаблять весь сайт ради одной функции.

4. Проверьте реальный ответ

Headers могут добавляться, перезаписываться, дублироваться или удаляться CDN, reverse proxies, app servers и middleware. Проверяйте финальный response в browser DevTools или с помощью command-line tools.

Также тестируйте embedded contexts. То, что top-level page выглядит корректно, не гарантирует, что iframe получил задуманное делегирование.

5. Документируйте исключения

У каждой разрешенной функции должны быть владелец и причина. Это звучит бюрократично ровно до момента через шесть месяцев, когда никто не помнит, почему geolocation была открыта для vendor domain, который больше не появляется на странице.

Распространенные синтаксические ошибки

Современный синтаксис заголовка компактен, но в нем легко немного ошибиться.

Используйте empty parentheses, чтобы запретить функцию:

Permissions-Policy: microphone=()

Используйте self для текущего origin:

Permissions-Policy: geolocation=(self)

Используйте quoted origins для конкретных внешних origins:

Permissions-Policy: fullscreen=(self "https://video.example")

Не полагайтесь на старые примеры Feature-Policy, если вы намеренно не поддерживаете legacy behavior. Старый заголовок использовал другой синтаксис, и сегодня не стоит проектировать вокруг него.

Также помните, что поддержка браузерами различается по directive. Браузер может поддерживать заголовок, но не конкретную feature directive. Это нормально. Рассматривайте заголовок как меру defense-in-depth, а не как единственный privacy или security control.

<!-- tool-cta:start -->

💡 Попробуйте это: Проверьте, что ваша Permissions-Policy доставляется как задумано, с помощью Get Headers, который показывает необработанные заголовки ответа, отправляемые вашим сервером.

<!-- tool-cta:end -->

Практическая ценность для приватности

Ценность Permissions-Policy для приватности не в том, что он делает сайт анонимным или свободным от trackers. Он этого не делает.

Его ценность в том, что он сужает доступ к чувствительным возможностям браузера. Location, camera, microphone, device sensors, local hardware APIs и payment flows — мощные функции. Большинству страниц они не нужны. Многие embedded components вообще не должны иметь возможности их запрашивать.

Это реальное улучшение. Оно сокращает случайные prompts, ограничивает ненужное раскрытие capabilities и дает вашей команде конкретный artifact для проверки при выпуске новой функциональности.

Лучшая версия этого заголовка — скучная: ограничительная по умолчанию, ослабленная только там, где этого требует пользовательская функция, и протестированная как часть обычного release process.

Часто задаваемые вопросы

Permissions-Policy — это то же самое, что Feature-Policy?
Нет. Permissions-Policy — современная замена старого заголовка Feature-Policy. Некоторые старые статьи и snippets все еще используют синтаксис Feature-Policy, но новые реализации должны использовать Permissions-Policy.
Может ли Permissions-Policy остановить сторонний tracking?
Сам по себе — нет. Он может блокировать доступ к некоторым функциям браузера, но не мешает скриптам загружаться, устанавливать cookies там, где это разрешено, читать содержимое страницы или отправлять сетевые запросы. Используйте его вместе с CSP, consent controls, минимизацией данных и тщательным управлением vendors.
Должен ли каждый сайт запрещать камеру и микрофон?
В большинстве случаев — да. Если ваш сайт не предоставляет запись видео, конференции, проверку личности или другую функцию, которой явно нужен media capture, запрет камеры и микрофона — разумное значение по умолчанию.
Может ли атрибут iframe allow переопределить заголовок?
Нет. Policy родительского документа задает верхний предел. Атрибут iframe allow может делегировать функцию только если parent policy разрешает эту функцию для frame origin.
Сломают ли неподдерживаемые directives старые браузеры?
Как правило, неподдерживаемые directives игнорируются. Тем не менее стоит тестировать важные user journeys во всех поддерживаемых браузерах, потому что поведение отдельных API и сообщения в console могут различаться.

Источники и дальнейшее чтение

  1. MDN Web Docs: Permissions-Policy header
  2. W3C: Permissions Policy specification
  3. web.dev: Permissions Policy
  4. Chrome Developers: Controlling browser features with Permissions Policy
Об авторе
The Wux Webtools Team

Последнее обновление:

Продолжайте читать

Privacy & Security

Почему обработка изображений в браузере — выигрыш для приватности

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

1 минуты чтения