Controlar las funciones del navegador con la política de permisos

Administra cómo tu página y los iframes de terceros de tu página tienen acceso a las funciones del navegador.

Kevin K. Lee
Kevin K. Lee

La Política de Permisos, antes conocida como Política de Funciones, permite que el desarrollador controlar las funciones del navegador disponibles para una página, sus iframes y subrecursos, mediante la declaración de un conjunto de políticas que el navegador debe aplicar. Estos las políticas se aplican a los orígenes proporcionados en una lista de orígenes de encabezado de respuesta. La lista de orígenes puede contener los mismos orígenes o orígenes cruzados, y permite al desarrollador controlar el acceso propio y de terceros a las funciones del navegador.

El usuario tiene la decisión final de permitir el acceso a funciones más potentes y debe dar permiso explícito a través de un mensaje.

La política de permisos permite que el sitio de nivel superior defina qué es partes pretenden utilizar y elimina la responsabilidad del usuario de determinar si la solicitud de acceso a las funciones es legítima o no. Por ejemplo, bloquear la función de ubicación geográfica para todos los terceros mediante la Política de Permisos el desarrollador puede estar seguro de que ningún tercero accederá a los datos del usuario la ubicación geográfica.

Cambios en la Política de Permisos

La política de permisos antes se conocía como política de funciones. Los conceptos clave siguen siendo los mismos, pero hay algunos cambios importantes junto con el nombre.

Uso de campos estructurados

Los campos estructurados proporcionan un conjunto de estructuras de datos comunes para estandarizar el análisis y la serialización de los valores de los campos de encabezado HTTP. Obtén más información sobre los campos estructurados en la entrada de blog de Fastly: “Cómo mejorar HTTP con campos de encabezado estructurados”.

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

Antes con la política de funciones.

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

Ahora con política de permisos.

Combina encabezados con el atributo iframe allow

Con la política de funciones, puedes agregar el atributo a un marco de origen cruzado agregando el origen a la lista de orígenes del encabezado o agregando un atributo allow a la etiqueta de iframe. Con la política de permisos, si agregas un marco de origen cruzado a la lista de orígenes, la etiqueta de iframe para ese origen debe incluir el atributo allow. Si la respuesta no contiene un encabezado de política de permisos, se considera que la lista de orígenes tiene el valor predeterminado de *. Si agregas el atributo allow al iframe, se permite el acceso a la función.

Por lo tanto, recomendamos que los desarrolladores establezcan de forma explícita el encabezado de la política de permisos en la respuesta, de modo que los iframes de origen cruzado que no aparecen en la lista de orígenes se bloqueen y no puedan acceder a esta función, incluso si allow está presente.

La política de funciones se podrá seguir usando después de Chrome 88, pero actúa como un alias para la Política de Permisos. Aparte de la sintaxis, no hay diferencia en la lógica. Si se usan juntos los encabezados de Política de permisos y Política de funciones, el encabezado Permissions-Policy tendrá mayor prioridad y reemplazará el valor proporcionado por el encabezado Feature-Policy.

¿Cómo uso la Política de Permisos?

Descripción general breve

Antes de profundizar, echemos un vistazo rápido a una situación común en la que tú eres el propietario de un sitio web y deseas controlar la manera en que tu sitio y el código de terceros utilizan las funciones del navegador.

  • Tu sitio es https://your-site.example.
  • Tu sitio incorpora un iframe del mismo origen (https://your-site.example).
  • Tu sitio incorpora un iframe de https://trusted-site.example en el que confías.
  • Tu sitio también muestra anuncios publicados por https://ad.example.
  • Quieres permitir la ubicación geográfica solo para tu sitio y el de confianza, no para el anuncio.

En este caso, usa el siguiente encabezado:

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

Además, configura de forma explícita el atributo allow en la etiqueta de iframe del sitio de confianza:

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

Diagrama de descripción general rápida del uso de la política de permisos.

En este ejemplo, la lista de origen del encabezado permite que solo tu sitio (self) y trusted-site.example usen la función de ubicación geográfica. ad.example no tiene permiso para usar la ubicación geográfica.

  1. Tu sitio your-site.example puede usar la función de ubicación geográfica con el consentimiento del usuario.
  2. Un iframe del mismo origen (your-site.example) puede utilizar la función sin utilizar el atributo allow.
  3. Un iframe publicado desde un subdominio diferente (subdomain.your-site-example) que no se agregó a la lista de orígenes y tiene el atributo de permiso establecido en la etiqueta de iframe no tiene permiso para usar la función. Los subdominios diferentes se consideran de un mismo sitio, pero de origen cruzado.
  4. Un iframe de origen cruzado (trusted-site.example) que se agregó a la lista de orígenes y tiene el atributo allow configurado en la etiqueta de iframe puede usar la función.
  5. Un iframe de origen cruzado (trusted-site.example) que se agrega a la lista de orígenes, sin el atributo allow, no puede usar la función.
  6. Un iframe de origen cruzado (ad.example) que no se agregó a la lista de orígenes no puede usar la función, incluso si el atributo allow está incluido en la etiqueta del iframe.

Encabezado de respuesta HTTP Permissions-Policy

El usuario realiza una solicitud, el servidor responde con el encabezado de la política de permisos y, luego, el navegador otorga el acceso en función de ese encabezado.

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

Usa un encabezado Permissions-Policy en la respuesta del servidor para establecer los orígenes permitidos para una función. El valor del encabezado puede tener una combinación de tokens y cadenas de orígenes. Los tokens disponibles son * para todos los orígenes y self para el mismo origen.

Si el encabezado es para varios atributos, sepáralos con una coma. Si enumeras varios orígenes, separa cada uno de ellos con un espacio. Para los encabezados que indican un origen que es una solicitud de origen cruzado, la etiqueta iframe debe incluir el atributo allow.

Estos son algunos ejemplos de pares clave-valor:

  • Sintaxis: [FEATURE]=*
    • Política que se aplica a todos los orígenes
    • Ejemplo: geolocation=*
  • Sintaxis: [FEATURE]=(self)
    • Política aplicada al mismo origen
    • Ejemplo: geolocation=(self)
  • Sintaxis: [FEATURE]=(self [ORIGIN(s)])
    • Política aplicada al mismo origen y a los orígenes especificados
    • Ejemplo: geolocation=(self "https://a.example" "https://b.example")
    • self es una abreviatura de https://your-site.example.
  • Sintaxis: [FEATURE]=([ORIGIN(s)])
    • Política aplicada al mismo origen y a los orígenes especificados
    • Ejemplo: geolocation=("https://your-site.example" "https://a.example" "https://b.example")
    • Cuando se usa esta sintaxis, uno de los orígenes debe ser el de la incorporación. Si no se otorgan los permisos a la página de incorporación, los iframes incorporados en esa página también se bloquearán, incluso aunque se agreguen a la lista de origen, ya que la política de permisos delega los permisos. También puedes usar el token self.
  • Sintaxis: [FEATURE]=()
    • Función bloqueada para todos los orígenes
    • Ejemplo: geolocation=()

Diferentes subdominios y rutas de acceso

Los subdominios diferentes, como https://your-site.example y https://subdomain.your-site.example, se consideran del mismo sitio, pero de origen cruzado. Por lo tanto, agregar un subdominio a la lista de orígenes no permite el acceso a otro subdominio del mismo sitio. Cada subdominio incorporado en el que se desee usar la función debe agregarse por separado a la lista de orígenes. Por ejemplo, si se permite el acceso a los temas de navegación del usuario al mismo origen solo con el encabezado Permissions-Policy: browsing-topics=(self), un iframe de un subdominio diferente del mismo sitio, https://subdomain.your-site.example, no tendrá acceso a los temas.

Las rutas diferentes, como https://your-site.example y https://your-site.example/embed, se consideran del mismo origen, y no es necesario que las diferentes rutas aparezcan en la lista de orígenes.

Atributo allow de iframe

Configuración de iframes

Para el uso de origen cruzado, un iframe necesita el atributo allow de la etiqueta para obtener acceso al componente.

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

Por ejemplo:

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

Cómo administrar la navegación de iframe

Configuración de la navegación de iframe

De forma predeterminada, si un iframe navega a otro origen, la política no se aplica al origen al que navega el iframe. Si enumeras el origen al que navega el iframe en el atributo allow, se aplicará la política de permisos que se aplicó al iframe original al origen al que navegue el iframe.

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

Puedes ver cómo funciona si visitas la demostración de navegación de iframe.

Ejemplos de configuraciones de políticas de permisos

Puedes encontrar los ejemplos de las siguientes configuraciones en la demostración.

Función permitida en todos los orígenes

Arquitectura de todos los orígenes autorizados para acceder a la función

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

Cuando se establece la lista de orígenes en el token *, se permite la función para todos los orígenes presentes en la página, incluidos él mismo y todos los iframes. En este ejemplo, todo el código entregado desde https://your-site.example y los códigos entregados desde el iframe https://trusted-site.example y https://ad.example tienen acceso a la función de ubicación geográfica en el navegador del usuario. Recuerda que el atributo allow también debe establecerse en el iframe, además de agregar el origen a la lista de orígenes del encabezado.

Puedes ver esta configuración en la demostración.

Función solo permitida para el mismo origen

Arquitectura que solo tiene el mismo origen que puede acceder a la función

Permissions-Policy: geolocation=(self)

El uso del token self permite el uso de la ubicación geográfica solo para el mismo origen. Los orígenes cruzados no tendrán acceso a la función. En este ejemplo, solo https://trusted-site.example (self) tendrá acceso a la ubicación geográfica. Usa esta sintaxis si quieres usar la función solo para tu página y no para otras.

Puedes ver esta configuración en la demostración.

Atributo permitido en el mismo origen y en orígenes cruzados específicos

Arquitectura de los orígenes especificados que pueden acceder a la función

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

Esta sintaxis permite usar la ubicación geográfica tanto para sí mismo (https://your-site.example) como para https://trusted-site.example. Recuerda agregar explícitamente el atributo allow a la etiqueta de iframe. Si hay otro iframe con <iframe src="https://ad.example" allow="geolocation">, https://ad.example no tendrá acceso a la función de ubicación geográfica. Solo la página original y las https://trusted-site.example que figuran en la lista de orígenes, junto con el atributo allow (permitir) en la etiqueta de iframe, tendrán acceso a la función del usuario.

Puedes ver esta configuración en la demostración.

Función bloqueada en todos los orígenes

Arquitectura de todos los orígenes con bloqueo para acceder a la función

Permissions-Policy: geolocation=()

Con una lista de orígenes vacía, el componente se bloquea para todos los orígenes. Puedes ver esta configuración en la demostración.

Usa la API de JavaScript

La API de JavaScript existente de la Política de funciones se encuentra como un objeto en el documento o el elemento (document.featurePolicy or element.featurePolicy). Aún no se implementó la política de la API de JavaScript para permisos.

La API de Feature Policy se puede usar para las políticas que establece la Política de Permisos, con algunas limitaciones. Hay preguntas restantes relacionadas con una implementación de la API de JavaScript, y se realizó una propuesta para mover la lógica a la API de Permissions. Si tienes ideas al respecto, únete al debate.

featurePolicy.allowsFeature(feature)

  • Muestra true si la función está permitida para el uso del origen predeterminado.
  • El comportamiento es el mismo para ambas políticas establecidas por la Política de Permisos y la Política de Funciones anterior.
  • Cuando se llama a allowsFeature() en un elemento del iframe (iframeEl.featurePolicy.allowsFeature('geolocation')), el valor que se muestra se refleja si el atributo allow está configurado en el iframe.

featurePolicy.allowsFeature(feature, origin)

  • Muestra true si el componente está permitido para el origen especificado.
  • Si se llama al método en document, este ya no te indica si el atributo está permitido para el origen especificado como lo hizo la Política de funciones. Ahora, este método te indicará que es posible que se permita el atributo en ese origen. Debes realizar una verificación adicional para comprobar si el iframe tiene configurado el atributo allow. El desarrollador debe realizar una verificación adicional del atributo allow en el elemento iframe para determinar si la función está permitida para el origen de terceros.

Comprueba las funciones en un iframe con el objeto element

Puedes usar element.allowsFeature(feature), que tenga en cuenta el atributo allow, a diferencia de document.allowsFeature(feature, origin) que no lo hace.

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

featurePolicy.allowedFeatures()

  • Muestra una lista de características permitidas para el uso del origen predeterminado.
  • El comportamiento es el mismo para ambas políticas establecidas por la Política de Permisos y la Política de Funciones.
  • Cuando el nodo asociado es un iframe, se tiene en cuenta el atributo allow.

featurePolicy.features()

  • Muestra una lista de las funciones disponibles en el navegador.
  • El comportamiento es el mismo para ambas políticas establecidas por la Política de Permisos y la Política de Funciones.

Integración de las Herramientas para desarrolladores de Chrome

Integración de las Herramientas para desarrolladores de Chrome con la Política de Permisos

Consulta cómo funciona la política de permisos en Herramientas para desarrolladores.

  1. Abre las Herramientas para desarrolladores de Chrome.
  2. Abre el panel Application para verificar las funciones permitidas y no permitidas de cada marco.
  3. En la barra lateral, selecciona el marco que deseas inspeccionar. Aparecerá una lista de las funciones que el fotograma seleccionado puede usar y una lista de las funciones que están bloqueadas en ese fotograma.

Migración desde política de funciones

Si actualmente usas el encabezado Feature-Policy, puedes implementar los siguientes pasos para migrar a la política de permisos.

Reemplaza los encabezados de política de funciones por encabezados de política de permisos

Dado que los encabezados de la política de funciones solo se admiten en los navegadores basados en Chromium y los encabezados de la política de permisos son compatibles desde Chrome 88, se recomienda actualizar los encabezados existentes con la política de permisos.

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

Antes con la política de funciones.

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

Ahora con política de permisos.

Actualiza el uso de document.allowsFeature(feature, origin)

Si usas el método document.allowsFeature(feature, origin) para verificar las funciones permitidas de los iframes, utiliza el método allowsFeature(feature) adjunto en el elemento iframe, y no el document que lo contiene. El método element.allowsFeature(feature) tiene en cuenta el atributo allow, mientras que document.allowsFeature(feature, origin) no.

Comprobando el acceso a las funciones con document

Para seguir usando document como nodo base, debes realizar una verificación adicional del atributo allow en la etiqueta de 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

En lugar de actualizar el código existente con document, se recomienda llamar a allowsFeature() en el objeto element, como en el ejemplo anterior.

API de informes

La API de Reporting proporciona un mecanismo de denuncia para las aplicaciones web de manera coherente, y la API de Reporting para los incumplimientos de la Política de Permisos está disponible como una función experimental.

Si deseas probar la función experimental, sigue la explicación y habilita la marca en chrome://flags/#enable-experimental-web-platform-features. Con la marca habilitada, puedes observar los incumplimientos de la política de permisos en Herramientas para desarrolladores, en la pestaña Aplicación:

En el siguiente ejemplo, se muestra cómo se puede construir el encabezado de la API de Reporting:

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;

En la implementación actual, puede recibir informes de incumplimiento de política sobre cualquier incumplimiento que se produzca en ese marco a través de la configuración de un extremo llamado "default" como el ejemplo anterior. Los submarcos requerirán su propia configuración de informes.

Más información

Para comprender mejor la política de permisos, consulta los siguientes recursos: