Що насправді може заблокувати заголовок Permissions-Policy
Практичний посібник про функції браузера, які можна обмежити, про те, що ви не можете контролювати, і про те, як упровадити заголовок, не зламавши корисну функціональність.
Зміст
- Коротка версія
- Що контролює Permissions-Policy
- Що він може заблокувати на ваших власних сторінках
- Що він може заблокувати в iframes
- Що він не може заблокувати
- Розумна політика за замовчуванням
- Як упровадити, не зламавши функціональність
- 1. Проведіть інвентаризацію використання функцій
- 2. Почніть у середовищі з низьким ризиком
- 3. Використовуйте політики для окремих сторінок там, де потрібно
- 4. Перевірте реальну відповідь
- 5. Документуйте винятки
- Поширені синтаксичні помилки
- Практична цінність для приватності
Коротка версія
Permissions-Policy — це HTTP-заголовок відповіді, який дає сайту змогу обмежувати доступ до певних функцій браузера: камери, мікрофона, геолокації, повноекранного режиму, платежів, сенсорів і довгого переліку менших API.
Це не універсальний щит приватності. Він не зупинить усе відстеження, не заблокує cookies, не запобігатиме мережевим запитам і не зробить сторонній JavaScript безпечним. Те, що він може робити добре, вужче, але все одно цінне: зменшувати можливості браузера, доступні вашим власним сторінкам і вбудованим фреймам.
Це важливо, бо сучасні вебсайти складаються з фрагментів аналітики, медіавставок, чат-віджетів, менеджерів згоди, рекламних скриптів, карт, платіжних сценаріїв і внутрішніх експериментів. Більшості цих компонентів не потрібен доступ до потужних API пристрою. Добра політика робить це явним.
Якщо ви вже перевіряєте заголовки в production, поєднайте цю роботу з прямою перевіркою фактичної відповіді. Наш посібник із налагодження редиректів і HTTP-заголовків у production описує звичку, яка тут має значення: перевіряти те, що браузер справді отримує, а не те, що, за вашим конфігураційним файлом, має відбутися.
Що контролює Permissions-Policy
Заголовок контролює доступ до іменованих функцій браузера. Точний список із часом змінюється, бо змінюються браузерні API, але поширені директиви включають:
cameramicrophonegeolocationfullscreenpaymentusbbluetoothaccelerometergyroscopemagnetometerscreen-wake-lockclipboard-readclipboard-writepublickey-credentials-getinterest-cohortу старіших обговореннях, нині переважно історичний пункт
Директива може дозволити функцію нікому, поточному origin або вибраним origins. Наприклад:
Permissions-Policy: camera=(), microphone=(), geolocation=(self)
Це означає, що камера й мікрофон вимкнені для документа та його вкладених контекстів перегляду, тоді як геолокація дозволена лише для того самого origin.
Більш дозвільний приклад:
Permissions-Policy: geolocation=(self "https://maps.example"), fullscreen=(self "https://video.example")
Це дозволяє вашому власному origin і одному вказаному постачальнику карт використовувати геолокацію, а вашому власному origin разом із постачальником відео — запитувати повноекранний режим.
Політику оцінює браузер. Якщо функцію заборонено, JavaScript, що використовує відповідний API, має завершитися помилкою або поводитися так, ніби функція недоступна. Точний режим відмови залежить від API. Іноді promise відхиляється. Іноді можливість просто не виглядає придатною до використання.
Що він може заблокувати на ваших власних сторінках
На first-party сторінках Permissions-Policy найкорисніший як запобіжник. Він зменшує радіус ураження від випадкового або неочікуваного коду.
Маркетинговій сторінці, наприклад, найімовірніше не потрібні мікрофон, камера, Bluetooth, USB, сенсори руху чи платіжні API. Ви можете заборонити ці функції глобально:
Permissions-Policy: camera=(), microphone=(), bluetooth=(), usb=(), payment=(), accelerometer=(), gyroscope=(), magnetometer=()
Це не робить кожен скрипт на сторінці надійним. Але це означає, що якщо експеримент у tag manager, скомпрометована залежність або вставлений віджет спробує викликати обмежений API, браузер не повинен надати йому доступ.
Для команд із великою кількістю учасників це корисне налаштування за замовчуванням. Воно переводить розмову від розмитої довіри до явної спроможності. Якщо майбутній функції справді потрібна камера, хтось має змінити політику й пояснити чому.
Це правильний вид тертя.
Що він може заблокувати в iframes
Заголовок стає особливо корисним довкола вбудованого контенту.
Браузери вже розглядають iframes як окремі контексти перегляду, але вбудований сторонній контент усе ще може запитувати потужні функції, якщо це дозволено політикою та атрибутами iframe. Permissions-Policy дає батьківській сторінці змогу встановити верхню межу.
Наприклад, якщо ваша сторінка вбудовує відеоплеєр, віджет підтримки й карту, ви можете не надавати кожному фрейму доступ до кожної функції. Ви можете дозволити повноекранний режим лише для відеофрейму, а геолокацію — лише для фрейму карти.
Є два рівні, які потрібно розуміти:
- HTTP-заголовок
Permissions-Policyзадає політику для документа. - Атрибут iframe
allowможе делегувати конкретні функції фрейму, але лише в межах того, що дозволяє батьківська політика.
Простий iframe може виглядати так:
<iframe src="https://video.example/embed/123" allow="fullscreen"></iframe>
Якщо ваш заголовок повністю забороняє повноекранний режим, атрибут iframe не може скасувати цю заборону. Якщо ваш заголовок дозволяє повноекранний режим для цього origin, атрибут iframe може його делегувати.
Ця ієрархія — одна з причин, чому заголовок варто використовувати. Він дає платформеним або безпековим командам спосіб задавати межі на рівні всього сайту, водночас дозволяючи продуктовим командам вмикати конкретні вбудовування там, де це потрібно.
Що він не може заблокувати
Саме тут команди іноді переоцінюють заголовок.
Permissions-Policy не замінює content security policy. Він не вирішує, які скрипти можуть завантажуватися. Він не зупиняє скрипт від надсилання даних через мережу. Він не санітизує HTML. Він не запобігає XSS. Він не блокує спам у формах. Якщо проблема у зловживанні формами, почніть із механіки, описаної в чому ваша контактна форма є найбільшим ризиком спаму, а не з цього заголовка.
Він також не замінює управління cookies. Cookies, local storage, згода, сторонні вбудовування та браузерні захисти від відстеження — це окремі питання. Якщо ви широко переглядаєте засоби приватності, ландшафт cookies потребує окремого проходу; практичні зміни описано в що змінилося для cookies у 2026 році і що з цим робити.
Найважливіше: Permissions-Policy не робить сторонній JavaScript приватним. Якщо ви завантажуєте сторонній скрипт у свою first-party сторінку, він зазвичай виконується з привілеями вашої сторінки, з урахуванням інших браузерних обмежень і ваших заголовків безпеки. Заборонити доступ до камери — добре. Але це не зупиняє скрипт від читання вмісту DOM, спостереження за діями користувача або виконання дозволених мережевих запитів.
Для цього потрібні інші засоби контролю: уважний вибір постачальників, CSP, sandboxed iframes, Subresource Integrity там, де це застосовно, мінімізація даних і нудні, але необхідні перевірки.
Розумна політика за замовчуванням
Немає універсального заголовка, який підходить кожному сайту, але більшість контентних і маркетингових сайтів можуть починати з обмежувального підходу.
Розумний перший варіант:
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), bluetooth=(), accelerometer=(), gyroscope=(), magnetometer=(), screen-wake-lock=()
Потім поверніть лише те, що сайт справді використовує.
Наприклад:
- Магазину, який використовує Payment Request API, може знадобитися
payment=(self). - Пошуку локацій може знадобитися
geolocation=(self)або довірений origin карт. - Застосунку для конференцій можуть знадобитися
camera=(self)іmicrophone=(self). - Сайту з великою кількістю відео може знадобитися
fullscreen=(self "https://trusted-video.example").
Важливо не скопіювати величезну політику з чекліста й вважати справу завершеною. Почніть з інвентаризації функцій. Яким сторінкам потрібні які можливості браузера? Яким вбудовуванням потрібне делегування? Запит яких функцій був би несподіваним?
Як упровадити, не зламавши функціональність
Впроваджуйте це як будь-який інший production-заголовок: обдумано.
1. Проведіть інвентаризацію використання функцій
Пошукайте в кодовій базі виклики браузерних API, як-от getUserMedia, geolocation, requestFullscreen, PaymentRequest, Web Bluetooth, WebUSB і wake lock APIs.
Потім перевірте сторонні вбудовування. Документація для відео, карт, платіжних і identity-провайдерів часто згадує потрібні значення iframe allow.
2. Почніть у середовищі з низьким ризиком
Додайте обмежувальний заголовок у staging і протестуйте основні сценарії. Звертайте увагу на повідомлення в консолі браузера. Браузери часто повідомляють, коли функцію заблоковано permissions policy.
3. Використовуйте політики для окремих сторінок там, де потрібно
Не змушуйте весь продукт жити з однією глобальною політикою, якщо в ньому є дуже різні типи сторінок. Блог, checkout, сторінка карти й відеокімната, ймовірно, потребують різних можливостей.
Більшість вебсерверів, фреймворків і edge-платформ можуть встановлювати заголовки умовно за шляхом. Це часто чистіше, ніж послаблювати весь сайт заради однієї функції.
4. Перевірте реальну відповідь
Заголовки можуть додаватися, перезаписуватися, дублюватися або видалятися CDN, reverse proxies, серверами застосунків і middleware. Перевіряйте фінальну відповідь у браузерних DevTools або за допомогою інструментів командного рядка.
Також тестуйте вбудовані контексти. Те, що верхньорівнева сторінка виглядає правильно, не гарантує, що iframe отримав делегування, яке ви планували.
5. Документуйте винятки
Кожна дозволена функція повинна мати власника й причину. Це звучить бюрократично до того моменту, коли за шість місяців ніхто вже не пам’ятає, чому geolocation було відкрито для домену постачальника, якого більше немає на сторінці.
Поширені синтаксичні помилки
Сучасний синтаксис заголовка компактний, але в ньому легко трохи помилитися.
Використовуйте порожні дужки, щоб заборонити функцію:
Permissions-Policy: microphone=()
Використовуйте self для поточного origin:
Permissions-Policy: geolocation=(self)
Використовуйте origins у лапках для конкретних зовнішніх origins:
Permissions-Policy: fullscreen=(self "https://video.example")
Не покладайтеся на старі приклади Feature-Policy, якщо ви навмисно не підтримуєте legacy-поведінку. Старіший заголовок використовував інший синтаксис, і сьогодні не варто проєктувати рішення навколо нього.
Також пам’ятайте, що підтримка браузерами відрізняється залежно від директиви. Браузер може підтримувати заголовок, але не підтримувати конкретну директиву функції. Це нормально. Розглядайте заголовок як захист у глибину, а не як єдиний засіб контролю приватності чи безпеки.
<!-- tool-cta:start -->
💡 Спробуйте це: Перевірте, чи ваша Permissions-Policy доставляється як задумано, за допомогою Get Headers, який показує необроблені заголовки відповіді, що надсилає ваш сервер.
<!-- tool-cta:end -->
Практична цінність для приватності
Цінність Permissions-Policy для приватності не в тому, що він робить сайт анонімним або вільним від трекерів. Він цього не робить.
Його цінність у тому, що він звужує доступ до чутливих можливостей браузера. Локація, камера, мікрофон, сенсори пристрою, локальні hardware APIs і платіжні сценарії — потужні інструменти. Більшості сторінок вони не потрібні. Багато вбудованих компонентів узагалі не повинні мати змоги їх запитувати.
Це реальне покращення. Воно зменшує випадкові запити дозволів, обмежує непотрібне розкриття можливостей і дає вашій команді конкретний артефакт для перевірки під час випуску нової функціональності.
Найкраща версія цього заголовка — нудна: обмежувальна за замовчуванням, послаблена лише там, де цього потребує видима для користувача функція, і протестована як частина звичайного процесу релізу.