Controlar os recursos do navegador com a política de permissões

Gerencie como sua página e os iframes de terceiros dela têm acesso aos recursos do navegador.

Kevin K. Lee
Kevin K. Lee

A política de permissões, antes conhecida como Política de recursos, permite que o desenvolvedor controlam os recursos do navegador disponíveis para uma página, seus iframes e sub-recursos, declarando um conjunto de políticas a serem aplicadas pelo navegador. Esses As políticas são aplicadas a origens fornecidas em uma lista de origens do cabeçalho de resposta. A lista de origens pode conter as mesmas origens e/ou origens cruzadas e permite o desenvolvedor controle o acesso primário e de terceiros aos recursos do navegador.

O usuário tem a decisão final de permitir o acesso a recursos mais avançados e precisa fornecer permissão explícita por meio de um comando.

A política de permissões permite que o site de nível superior defina o que ele e o terceiro as partes pretendem usar e remove o ônus do usuário de determinar se a solicitação de acesso a recursos é legítima ou não. Por exemplo, bloquear o recurso de geolocalização para todos os terceiros pela Política de permissões o desenvolvedor pode ter certeza de que nenhum terceiro terá acesso às configurações geolocalização.

Mudanças na política de permissões

A política de permissões era conhecida como política de recursos. Os conceitos principais permanecem os mesmos, mas há algumas mudanças importantes no nome.

Uso de campos estruturados

Os campos estruturados fornecem um conjunto de estruturas de dados comuns para padronizar a análise e a serialização dos valores do campo do cabeçalho HTTP. Saiba mais sobre os campos estruturados na postagem do blog da Fastly, "Como melhorar o HTTP com campos de cabeçalho estruturados".

Antigo
  geolocation 'self' https://example.com; camera 'none'

Antes, com a Política de recursos.

Novo
  geolocation=(self "https://example.com"), camera=()

Agora com a política de permissões.

Combinar cabeçalhos com o atributo allow de iframe

Com a Política de recursos, é possível adicionar o recurso a um frame de origem cruzada adicionando a origem à lista de origens do cabeçalho ou um atributo allow à tag de iframe. Com a política de permissões, se você adicionar um frame de origem cruzada à lista de origens, a tag de iframe dessa origem precisará incluir o atributo allow. Se a resposta não tiver um cabeçalho de política de permissões, será considerado que a lista de origens tem o valor padrão *. Adicionar o atributo allow ao iframe permite acesso ao recurso.

Portanto, recomendamos que os desenvolvedores definam explicitamente o cabeçalho da Política de permissões na resposta. Assim, os iframes de origem cruzada que não estiverem na lista de origens serão impedidos de acessar esse recurso, mesmo que allow esteja presente.

A política de recursos ainda pode ser usada após o Chrome 88, mas funciona como um alias da política de permissões. Além da sintaxe, não há diferença na lógica. Se os cabeçalhos da Política de permissões e da Política de recursos forem usados juntos, o cabeçalho Permissions-Policy terá maior prioridade e vai substituir o valor fornecido pelo cabeçalho Feature-Policy.

Como faço para usar a política de permissões?

Visão rápida

Antes de nos aprofundarmos, vamos analisar rapidamente um cenário comum em que você é proprietário de um site e quer controlar como seu site e o código de terceiros usam os recursos do navegador.

  • Seu site é https://your-site.example.
  • Seu site incorpora um iframe da mesma origem (https://your-site.example).
  • Seu site incorpora um iframe do https://trusted-site.example em que você confia.
  • Seu site também exibe anúncios veiculados por https://ad.example.
  • Você quer permitir geolocalização apenas para seu site e site confiável, não para o anúncio.

Nesse caso, use o seguinte cabeçalho:

Permissions-Policy: geolocation=(self "https://trusted-site.example")

E defina explicitamente o atributo allow como a tag de iframe do site confiável:

<iframe src="https://trusted-site.example" allow="geolocation">

Diagrama com visão geral rápida do uso da política de permissões.

Neste exemplo, a lista de origem do cabeçalho permite que apenas seu site (self) e trusted-site.example usem o recurso de geolocalização. ad.example não tem permissão para usar geolocalização.

  1. Seu site your-site.example tem permissão para usar o recurso de geolocalização com o consentimento do usuário.
  2. Um iframe de mesma origem (your-site.example) pode usar o recurso sem o atributo allow.
  3. Um iframe veiculado de um subdomínio diferente (subdomain.your-site-example) que não foi adicionado à lista de origem e tem o atributo "permitir" definido na tag do iframe está impedido de usar o recurso. Subdomínios diferentes são considerados como o mesmo site, mas têm origem cruzada.
  4. Um iframe de origem cruzada (trusted-site.example) que foi adicionado à lista de origens e tem o atributo allow definido na tag de iframe pode usar o recurso.
  5. Um iframe de origem cruzada (trusted-site.example) adicionado à lista de origens, sem o atributo allow, está impedido de usar o recurso.
  6. Um iframe de origem cruzada (ad.example) que não foi adicionado à lista de origem não pode usar o recurso, mesmo que o atributo allow esteja incluído na tag de iframe.

Cabeçalho de resposta HTTP Permissions-Policy

O usuário faz uma solicitação, o servidor responde com o cabeçalho &quot;Política de permissões&quot; e, em seguida, o navegador concede acesso com base nesse cabeçalho.

Permissions-Policy: &lt;feature&gt;=(&lt;token&gt;|&lt;origin(s)&gt;)

Use um cabeçalho Permissions-Policy na resposta do servidor para definir as origens permitidas para um recurso. O valor do cabeçalho pode ter uma combinação de tokens e strings de origens. Os tokens disponíveis são * para todas as origens e self para a mesma origem.

Se o cabeçalho for para vários recursos, separe-os com uma vírgula. Se você listar várias origens, separe cada uma na lista com um espaço. Para cabeçalhos que listam uma origem que é uma solicitação de origem cruzada, a tag de iframe precisa incluir o atributo allow.

Aqui estão alguns exemplos de pares de chave-valor:

  • Sintaxe: [FEATURE]=*
    • Política aplicada a todas as origens
    • Exemplo: geolocation=*
  • Sintaxe: [FEATURE]=(self)
    • Política aplicada à mesma origem
    • Exemplo: geolocation=(self)
  • Sintaxe: [FEATURE]=(self [ORIGIN(s)])
    • Política aplicada à mesma origem e às origens especificadas
    • Exemplo: geolocation=(self "https://a.example" "https://b.example")
    • self é uma abreviação de https://your-site.example.
  • Sintaxe: [FEATURE]=([ORIGIN(s)])
    • Política aplicada à mesma origem e às origens especificadas
    • Exemplo: geolocation=("https://your-site.example" "https://a.example" "https://b.example")
    • Ao usar essa sintaxe, uma das origens deve ser a origem do incorporador. Se a própria página de incorporação não receber as permissões, os iframes incorporados nessa página também serão bloqueados, mesmo que sejam adicionados à lista de origem, porque a política de permissões delega permissões. Também é possível usar o token self.
  • Sintaxe: [FEATURE]=()
    • Recurso bloqueado para todas as origens
    • Exemplo: geolocation=()
.

Subdomínios e caminhos diferentes

Subdomínios diferentes, como https://your-site.example e https://subdomain.your-site.example, são considerados mesmo site, mas têm origem cruzada. Portanto, adicionar um subdomínio à lista de origens não permite o acesso a outro subdomínio do mesmo site. Cada subdomínio incorporado que quiser usar o recurso precisa ser adicionado separadamente à lista de origem. Por exemplo, se o acesso aos temas de navegação do usuário tiver permissão para a mesma origem apenas com o cabeçalho Permissions-Policy: browsing-topics=(self), um iframe de um subdomínio diferente do mesmo site, https://subdomain.your-site.example, não terá acesso aos temas.

Caminhos diferentes, como https://your-site.example e https://your-site.example/embed, são considerados de mesma origem e não precisam ser listados na lista de origens.

Atributo do iframe allow

Configuração de iframes

Para uso de várias origens, um iframe precisa do atributo allow na tag para ter acesso ao recurso.

Sintaxe: <iframe src="[ORIGIN]" allow="[FEATURE] <'src' | [ORIGIN(s)]"></iframe>

Exemplo:

<iframe src="https://trusted-site.example" allow="geolocation">

Como processar a navegação do iframe

Configuração da navegação com iframe

Por padrão, se um iframe navegar para outra origem, a política não será aplicada àquela em que o iframe navega. Ao listar a origem de navegação do iframe no atributo allow, a política de permissões aplicada ao iframe original será aplicada à origem de navegação do iframe.

<iframe src="https://trusted-site.example" allow="geolocation https://trusted-site.example https://trusted-navigated-site.example">

É possível vê-lo em ação visitando a demonstração de navegação de iframe.

Exemplos de configurações da política de permissões

Os exemplos das configurações a seguir podem ser encontrados na demonstração.

Recurso permitido em todas as origens

Arquitetura de todas as origens com permissão para acessar o recurso

Permissions-Policy: geolocation=*
<iframe src="https://trusted-site.example" allow="geolocation">
<iframe src="https://ad.example" allow="geolocation">

Quando a lista de origens está definida como o token *, o recurso é permitido para todas as origens presentes na página, incluindo ela mesma e todos os iframes. Neste exemplo, todo o código exibido por https://your-site.example e os códigos exibidos pelo iframe https://trusted-site.example e pelo https://ad.example têm acesso ao recurso de geolocalização no navegador do usuário. Lembre-se de que o atributo allow também precisa ser definido no próprio iframe, além de adicionar a origem à lista de origens do cabeçalho.

Confira essa configuração na demonstração.

Recurso permitido apenas na mesma origem

Arquitetura da mesma origem que tem permissão para acessar o recurso

Permissions-Policy: geolocation=(self)

Com o token self, é possível usar a geolocalização apenas para a mesma origem. Origens cruzadas não terão acesso ao recurso. Neste exemplo, apenas https://trusted-site.example (self) terá acesso à geolocalização. Use essa sintaxe se quiser que o recurso seja exclusivo para sua página e mais ninguém.

Confira essa configuração na demonstração.

Recurso permitido na mesma origem e em origens cruzadas específicas

Arquitetura de origens especificadas que têm permissão para acessar o recurso

Permissions-Policy: geolocation=(self "https://trusted-site.example")

Essa sintaxe permite usar a geolocalização para si mesmo (https://your-site.example) e https://trusted-site.example. Lembre-se de adicionar explicitamente o atributo allow à tag iframe. Se houver outro iframe com <iframe src="https://ad.example" allow="geolocation">, https://ad.example não terá acesso ao recurso de geolocalização. Somente a página original e o https://trusted-site.example que está na lista de origens, além do atributo de permissão na tag iframe, terão acesso ao recurso do usuário.

Confira essa configuração na demonstração.

Recurso bloqueado em todas as origens

Arquitetura de todas as origens bloqueada de acessar o recurso

Permissions-Policy: geolocation=()

Com uma lista de origem vazia, o recurso é bloqueado para todas as origens. Confira essa configuração na demonstração.

Usar a API JavaScript

A API JavaScript atual da política de recursos é encontrada como um objeto no documento ou no elemento (document.featurePolicy or element.featurePolicy). A API JavaScript para a política de permissões ainda não foi implementada.

A API Feature Policy pode ser usada para políticas definidas pela Política de permissões, com algumas limitações. Há outras dúvidas sobre a implementação da API JavaScript, e foi feita uma proposta para mover a lógica para a API Permissions. Participe da discussão se você tiver alguma ideia.

featurePolicy.allowsFeature(feature)

  • Retornará true se o recurso for permitido para o uso de origem padrão.
  • O comportamento é o mesmo para as duas políticas definidas pela Política de permissões e pela política de recursos anterior
  • Quando allowsFeature() é chamado em um elemento iframe (iframeEl.featurePolicy.allowsFeature('geolocation')), o valor retornado reflete se o atributo de permissão está definido no iframe.

featurePolicy.allowsFeature(feature, origin)

  • Retorna true se o recurso for permitido para a origem especificada.
  • Se o método for chamado em document, esse método não informará mais se o recurso é permitido para a origem especificada, como a Política de recursos fez. Agora, esse método informa que é possível que o recurso seja permitido nessa origem. É necessário realizar uma verificação adicional para saber se o iframe tem o atributo allow definido ou não. O desenvolvedor precisa realizar uma verificação adicional do atributo allow no elemento iframe para determinar se o recurso é permitido para a origem de terceiros.

Verificar se há recursos em um iframe com o objeto element

Você pode usar element.allowsFeature(feature), que considera o atributo de permissão, ao contrário do document.allowsFeature(feature, origin), que não considera esse atributo.

const someIframeEl = document.getElementById('some-iframe')
const isCameraFeatureAllowed = someIframeEl.featurePolicy.allowsFeature('camera')

featurePolicy.allowedFeatures()

  • Retorna uma lista de recursos permitidos para o uso de origem padrão.
  • O comportamento é o mesmo para as duas políticas definidas pela Política de permissões e pela Política de recursos
  • Quando o nó associado é um iframe, o atributo de permissão é considerado.

featurePolicy.features()

  • Retorna uma lista de recursos disponíveis no navegador.
  • O comportamento é o mesmo para as duas políticas definidas pela Política de permissões e pela Política de recursos

Integração com o Chrome DevTools

Integração do Chrome DevTools com a política de permissões

Confira como a política de permissões funciona no DevTools.

  1. Abra o Chrome DevTools.
  2. Abra o painel Aplicativo para verificar os recursos permitidos e não permitidos de cada frame.
  3. Na barra lateral, selecione o frame que você quer inspecionar. Você verá uma lista de recursos que o frame selecionado pode usar e uma lista de recursos que estão bloqueados nesse frame.

Migração da política de recursos

Se você estiver usando o cabeçalho Feature-Policy, implemente as etapas a seguir e migre para a política de permissões.

Substituir cabeçalhos da política de recursos por cabeçalhos da política de permissões

Como os cabeçalhos da política de recursos só são compatíveis com navegadores baseados no Chromium, e os cabeçalhos da política de permissões são compatíveis desde o Chrome 88, é seguro atualizar os cabeçalhos existentes com a política de permissões.

Antigo
Feature-Policy:
  autoplay *;
  geolocation 'self';
  camera 'self' 'https://trusted-site.example';
  fullscreen 'none';

Antes, com a Política de recursos.

Novo
Permissions-Policy:
  autoplay=*,
  geolocation=(self),
  camera=(self "https://trusted-site.example"),
  fullscreen=()

Agora com a política de permissões.

Atualizar o uso do document.allowsFeature(feature, origin)

Se você estiver usando o método document.allowsFeature(feature, origin) para verificar os recursos permitidos para iframes, use o método allowsFeature(feature) anexado ao elemento iframe, e não o document que o contém. O método element.allowsFeature(feature) considera o atributo allow, mas document.allowsFeature(feature, origin) não.

Verificando acesso ao recurso com document

Para continuar usando document como nó base, será necessário realizar uma verificação adicional do atributo allow na tag 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

Em vez de atualizar o código já existente usando document, é recomendável chamar allowsFeature() no objeto element, como no exemplo anterior.

API Reporting

A API Reporting fornece um mecanismo de relatórios para aplicativos da Web de maneira consistente. A API Reporting para violações da política de permissões está disponível como um recurso experimental.

Se você quiser testar o recurso experimental, siga o tutorial e ative a flag em chrome://flags/#enable-experimental-web-platform-features. Com a flag ativada, é possível observar as violações da política de permissões no DevTools na guia Application:

O exemplo a seguir mostra como o cabeçalho da API Reporting pode ser criado:

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;

Na implementação atual, você pode receber relatórios de violação da política de qualquer violação ocorrida nesse frame configurando um endpoint chamado "default" como no exemplo acima. Os subframes precisam de uma configuração própria para geração de relatórios.

Saiba mais

Para entender melhor a política de permissões, consulte os seguintes recursos: