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

Administra cómo tu página y los iframes de terceros en 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 al 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. Estas políticas se aplican a los orígenes proporcionados en una lista de orígenes de encabezado de respuesta. La lista de origen puede contener orígenes iguales o cruzados y permite al desarrollador controlar el acceso de origen o de terceros a las funciones del navegador.

El usuario tiene la decisión final de permitir el acceso a funciones más potentes y necesita proporcionar permiso explícito mediante una instrucción.

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 carga de determinar si la solicitud de acceso a las funciones es legítima o no. Por ejemplo, si bloqueas la función de ubicación geográfica de todos los terceros a través de la Política de Permisos, el desarrollador puede tener la certeza de que ningún tercero obtendrá acceso a la ubicación geográfica del usuario.

Cambios en la Política de Permisos

Anteriormente, la Política de Permisos 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 campo del encabezado HTTP. Obtén más información sobre los campos estructurados en la entrada de blog de Fastly, "Improving HTTP withstruct header Fields".

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

Antes con la política de funciones.

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

Ahora veremos la Política de Permisos.

Combina encabezados con el atributo iframe allow

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

Por lo tanto, recomendamos a los desarrolladores que establezcan explícitamente el encabezado de la Política de Permisos en la respuesta para que los iframes de origen cruzado que no aparezcan en la lista de origen se bloqueen y puedan acceder 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 los encabezados de la política de permisos y la política de funciones se usan juntos, 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, observemos rápidamente una situación común en la que eres el propietario de un sitio web y quieres controlar la manera en que el 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 de confianza.
  • Tu sitio también muestra anuncios publicados por https://ad.example.
  • Quieres permitir la ubicación geográfica solo para tu sitio y el sitio de confianza, no para el anuncio.

En ese caso, usa el siguiente encabezado:

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

Además, establece 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 breve 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 permitido usar la ubicación geográfica.

  1. Tu sitio your-site.example tiene permitido usar la función de ubicación geográfica con el consentimiento del usuario.
  2. Un iframe del mismo origen (your-site.example) puede usar la función sin el uso del atributo allow.
  3. Un iframe publicado desde un subdominio diferente (subdomain.your-site-example) que no se agregó a la lista de origen y que tiene el atributo de permiso configurado en la etiqueta del iframe está bloqueado para usar esta función. Los subdominios diferentes se consideran en el mismo sitio, pero tienen orígenes cruzados.
  4. Un iframe de origen cruzado (trusted-site.example) que se haya agregado a la lista de origen y que tenga el atributo allow configurado en la etiqueta del iframe puede usar la función.
  5. Si se agrega un iframe de origen cruzado (trusted-site.example) a la lista de origen, sin el atributo allow, no se puede usar la función.
  6. Un iframe de origen cruzado (ad.example) que no se agregó a la lista de origen 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 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 un componente. 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 tu encabezado es para varios elementos, separa cada uno de ellos con una coma. Si enumeras varios orígenes, separa cada uno de ellos en la lista 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 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 origen del embedder. Si la página del incorporado en sí no recibe los permisos, también se bloquearán los iframes incorporados en esa página, aunque se agreguen a la lista de origen porque la Política de Permisos delega permisos. También puedes usar el token self.
  • Sintaxis: [FEATURE]=()
    • Se bloqueó una función 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 en la lista de origen no permite el acceso a otro subdominio del mismo sitio. Cada subdominio incorporado que desee utilizar la función debe agregarse por separado a la lista de origen. Por ejemplo, si se permite el acceso a los temas de navegación del usuario para el 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 diferentes rutas de acceso, 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 de iframe allow

Configuración de iframes

Para el uso de orígenes cruzados, 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 manejar 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 indicas 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">

Puedes verlo en acción si consultas la demostración de navegación de iframe.

Ejemplos de configuración de la política de permisos

En la demostración, puedes encontrar los ejemplos de las siguientes configuraciones.

Función permitida en todos los orígenes

Arquitectura de todos los orígenes permitidos para acceder al componente

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 *, se permite la función para todos los orígenes presentes en la página, incluidos ellos mismos y todos los iframes. En este ejemplo, todo el código publicado desde https://your-site.example y desde el iframe y https://ad.example de https://trusted-site.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 configurarse 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.

La función solo está permitida en el mismo origen

Arquitectura del mismo origen que tiene permiso para acceder al elemento

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 que la función solo se aplique a tu página y nada más.

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

Se permite la función en orígenes cruzados específicos y en el mismo origen

Arquitectura de orígenes especificados con permiso para acceder al componente

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

Esta sintaxis permite el uso de la ubicación geográfica tanto para él (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 el https://trusted-site.example que aparecen en la lista de origen junto con el atributo de permiso en la etiqueta de iframe tendrán acceso a la función del usuario.

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

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

Se bloqueó el acceso a la función con la arquitectura de todos los orígenes.

Permissions-Policy: geolocation=()

Si la lista de orígenes está vacía, se bloqueará el elemento 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 en el elemento (document.featurePolicy or element.featurePolicy). Aún no se implementó la API de JavaScript para la Política de Permisos.

La API de Feature Policy se puede usar para las políticas establecidas por la política de permisos, con algunas limitaciones. Hay preguntas restantes sobre la implementación de la API de JavaScript y se realizó una propuesta para mover la lógica a la API de Permissions. Únete al debate si tienes alguna duda.

featurePolicy.allowsFeature(feature)

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

featurePolicy.allowsFeature(función, origen)

  • Muestra true si el elemento está permitido para el origen especificado.
  • Si se llama al método en document, este ya no te indicará si la función está permitida para el origen especificado, como lo hizo la política de funciones. Ahora, este método te indica que es posible que el atributo 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 del iframe para determinar si la función está permitida para el origen de terceros.

Verifica las funciones de un iframe con el objeto element

Puedes usar element.allowsFeature(feature), que tiene en cuenta el atributo allow (permitir), 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 las funciones permitidas para el uso del origen predeterminado.
  • El comportamiento es el mismo para las 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 las 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. Abra las Herramientas para desarrolladores de Chrome.
  2. Abre el panel Aplicación para comprobar las funciones permitidas y las no permitidas de cada fotograma.
  3. En la barra lateral, selecciona el marco que deseas inspeccionar. Verás 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 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 se admiten 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 veremos 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 de los iframes, usa el método allowsFeature(feature) adjunto en el elemento del iframe y no el document contenedor. El método element.allowsFeature(feature) tiene en cuenta el atributo allow, mientras que document.allowsFeature(feature, origin) no lo hace.

Verificando 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 del 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 generación de informes para las aplicaciones web de manera coherente, y la API de Reporting por incumplimientos de la política de permisos está disponible como función experimental.

Si quieres 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 infracciones a 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 informes:

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 incumplimiento de política de cualquier incumplimiento que ocurra en ese marco configurando un extremo llamado "default", como en el ejemplo anterior. Los submarcos necesitarán su propia configuración de informes.

Más información

Para comprender mejor la Política de Permisos, consulta los siguientes recursos: