Controla las funciones del navegador con la Política de Permisos

Administra cómo tu página y los iframes de terceros en ella 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, le permite al desarrollador controlar las funciones del navegador disponibles para una página, sus iframes y subrecursos a través de la declaración de un conjunto de políticas que el navegador debe aplicar. Estas 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 orígenes iguales o 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 aceptar un mensaje para proporcionar un permiso explícito.

La Política de Permisos permite que el sitio de nivel superior defina lo que él y sus terceros pretenden usar, y le quita al usuario la responsabilidad de determinar si la solicitud de acceso a la función es legítima o no. Por ejemplo, si se usa la Política de Permisos para bloquear la función de ubicación geográfica para todos los terceros, el desarrollador puede asegurarse de que ningún tercero obtenga acceso a la ubicación geográfica del usuario.

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 "Mejora 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 la 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 de 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 *. Agregar el atributo allow al iframe permite el acceso a la función.

Por lo tanto, recomendamos que los desarrolladores configuren explícitamente el encabezado de la Política de Permisos en la respuesta para que se bloquee el acceso de los iframes de origen cruzado que no aparecen en la lista de orígenes a esta función, incluso si allow está presente.

La Política de funciones se puede seguir usando después de Chrome 88, pero actúa como un alias de la Política de permisos. Aparte de la sintaxis, no hay diferencia en la lógica. Si se usan juntos los encabezados de la Política de Permisos y de la Política de Funciones, el encabezado Permissions-Policy tendrá una prioridad más alta 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 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.
  • Debes 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")

Y establece explícitamente el atributo allow en la etiqueta de iframe del sitio de confianza:

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

Descripción general 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 geolocalización. ad.example no tiene permitido usar la ubicación geográfica.

  1. Tu sitio your-site.example puede usar la función de geolocalización 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 del mismo sitio, pero de origen diferente.
  4. Un iframe de origen cruzado (trusted-site.example) que se agregó a la lista de orígenes y tiene el atributo allow establecido 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. Se bloquea el uso de la función en un iframe de origen cruzado (ad.example) que no se agregó a la lista de orígenes, incluso si el atributo allow se incluye en la etiqueta de 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 acceso en función de ese encabezado.

Permissions-Policy: <feature>=(<token>|<origin(s)>)

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 aceptar 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 con un espacio. En el caso de los encabezados que enumeran un origen que es una solicitud de origen cruzado, la etiqueta de iframe debe incluir el atributo allow.

Estos son algunos ejemplos de pares clave-valor:

  • Sintaxis: [FEATURE]=*
    • Política aplicada a todos los orígenes
    • Ejemplo: geolocation=*
  • Sintaxis: [FEATURE]=(self)
    • Política aplicada a origen-igual
    • 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 del incorporador. Si no se le otorgan los permisos a la página de incorporación, los iframes incorporados en esa página también se bloquearán aunque se hayan agregado 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

Los diferentes subdominios, como https://your-site.example y https://subdomain.your-site.example, se consideran del mismo sitio, pero de origen diferente. 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 se incluyan en la lista de orígenes.

Atributo allow del iframe

Configuración del iframe

Para el uso entre orígenes, un iframe necesita el atributo allow en la etiqueta para obtener acceso a la función.

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

Por ejemplo:

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

Cómo controlar la navegación de iframe

Configuración de 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, la Política de Permisos que se aplicó al iframe original se aplicará al origen al que navega el iframe.

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

Para ver cómo funciona, visita la demo 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 la lista de orígenes se establece en el token *, la función se permite para todos los orígenes presentes en la página, incluido el propio origen 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, junto con el agregado del origen a la lista de orígenes del encabezado.

Puedes ver esta configuración en la demo.

La función solo se permite en 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.

Función permitida 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 el uso de la geolocalización para sí mismo (https://your-site.example) y https://trusted-site.example. Recuerda agregar explícitamente el atributo allow a la etiqueta 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 el https://trusted-site.example que se incluye en la lista de origen, junto con el atributo allow en la etiqueta de iframe, tendrán acceso a la función del usuario.

Puedes ver esta configuración en la demo.

Se bloqueó la función en todos los orígenes

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

Permissions-Policy: geolocation=()

Si la lista de orígenes está vacía, la función 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 Feature Policy se encuentra como un objeto en el documento o en el elemento (document.featurePolicy or element.featurePolicy). La API de JavaScript para la Política de Permisos aún no se implementó.

La API de Feature Policy se puede usar para las políticas que establece la Política de Permisos, con algunas limitaciones. Quedan preguntas sobre la implementación de una API de JavaScript, y se realizó una propuesta para trasladar la lógica a la API de Permissions. Únete al debate si tienes alguna idea.

featurePolicy.allowsFeature(feature)

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

featurePolicy.allowsFeature(feature, origin)

  • Muestra true si se permite la función para el origen especificado.
  • Si se llama al método en document, este ya no te indica si la función está permitida para el origen especificado, como lo hacía la Política de funciones. Ahora, este método te indica que es posible que la función se permita 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.

Cómo verificar si hay componentes en un iframe con el objeto element

Puedes usar element.allowsFeature(feature), que tiene 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 funciones permitidas para el uso de 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 Chrome DevTools

Integración de Chrome DevTools 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 Feature-Policy

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

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

Dado que los encabezados de la Política de funciones solo son compatibles con los navegadores basados en Chromium y los encabezados de la Política de permisos son compatibles desde Chrome 88, es seguro 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 la 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 para los iframes, usa el método allowsFeature(feature) adjunto al 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.

Cómo verificar el acceso a las funciones con document

Para seguir usando document como el 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 informes para aplicaciones web de manera coherente, y la API de Reporting para incumplimientos de la Política de Permisos está disponible como una función experimental.

Si quieres probar la función experimental, sigue la descripció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, puedes recibir informes de incumplimientos de política de cualquier incumplimiento que se produzca dentro de ese período configurando un extremo llamado "default", como en 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: