Introducción a la política de funciones

Resumen

La Política de funciones permite a los desarrolladores web habilitar, inhabilitar y modificar de manera selectiva el comportamiento de ciertas APIs y funciones web en el navegador. Es como la CSP, pero en lugar de controlar la seguridad, controla las funciones.

Las políticas de funciones en sí son pequeños acuerdos de aceptación entre el desarrollador y el navegador que pueden ayudar a fomentar nuestros objetivos de compilación (y mantenimiento) de apps web de alta calidad.

Introducción

Crear contenido para la Web es una aventura rocosa. Ya es difícil compilar una app web de primer nivel que mejora el rendimiento y usa todas las prácticas recomendadas más recientes. Es aún más difícil mantener una buena experiencia a lo largo del tiempo. A medida que tu proyecto evoluciona, se suman los desarrolladores, llegan nuevas funciones y crece la base de código. Esa gran experiencia TM que una vez conseguiste puede comenzar a deteriorarse y la UX comienza a verse afectada. La política de funciones está diseñada para mantenerte al día.

Con la Política de funciones, habilitas un conjunto de "políticas" para que el navegador aplique funciones específicas que se usan en tu sitio. Estas políticas restringen a qué APIs puede acceder el sitio, o bien modifican el comportamiento predeterminado del navegador para determinadas funciones.

Estos son algunos ejemplos de lo que puedes hacer con la política de funciones:

  • Cambia el comportamiento predeterminado de autoplay en dispositivos móviles y videos de terceros.
  • Impide que un sitio use APIs sensibles, como camera o microphone.
  • Permitir que los iframes usen la API de fullscreen
  • Bloquea el uso de APIs desactualizadas, como XHR síncrona y document.write().
  • Asegúrate de que las imágenes tengan el tamaño adecuado (p.ej., evita la hiperpaginación del diseño) y que no sean demasiado grandes para el viewport (p.ej., el ancho de banda del usuario desperdiciado).

Las políticas son un contrato entre el desarrollador y el navegador. Informan al navegador sobre la intención del desarrollador y, por lo tanto, nos ayudan a mantener la honestidad cuando nuestra app intenta descarrilarse y hacer algo malo. Si el sitio o el contenido de terceros incorporado intentan infringir alguna de las reglas preseleccionadas por el desarrollador, el navegador anula el comportamiento con una mejor UX o bloquea la API por completo.

Uso de la política de funciones

La política de funciones proporciona dos formas de controlar las funciones:

  1. A través del encabezado HTTP Feature-Policy
  2. Con el atributo allow en iframes

La forma más fácil de usar la política de funciones es enviar el encabezado HTTP Feature-Policy con la respuesta de una página. El valor de este encabezado es una política o un conjunto de políticas que deseas que el navegador respete para un origen determinado:

Feature-Policy: <feature> <allow list origin(s)>

La lista de entidades permitidas de origen puede tener varios valores diferentes:

  • *: La función se permite en contextos de navegación de nivel superior y en contextos de navegación anidados (iframes).
  • 'self': La función se permite en contextos de navegación de nivel superior y en contextos de navegación anidada del mismo origen. No está permitido en documentos de origen cruzado en contextos de navegación anidados.
  • 'none': La función no se permite en los contextos de navegación de nivel superior ni en los contextos de navegación anidada.
  • <origin(s)>: Orígenes específicos para los que se habilitará la política (p.ej., https://example.com).

Ejemplo

Supongamos que quieres bloquear todo el contenido para evitar que use la API de Geolocation. Para ello, envía una lista de entidades permitidas estricta de 'none' para la función geolocation:

Feature-Policy: geolocation 'none'

Si un fragmento de código o iframe intenta usar la API de Geolocation, el navegador lo bloquea. Esto se aplica incluso si el usuario ya había otorgado permiso para compartir su ubicación.

Incumplimiento de la política establecida de ubicación geográfica
Se incumple la política de ubicación geográfica establecida.

En otros casos, puede que tenga sentido flexibilizar un poco esta política. Para permitir que nuestro propio origen use la API de Geolocation, pero evitar que el contenido de terceros acceda a ella, configura 'self' en la lista de permitidos:

Feature-Policy: geolocation 'self'

El atributo iframe allow

La segunda forma de usar la política de funciones es controlar el contenido dentro de una iframe. Usa el atributo allow para especificar una lista de políticas para el contenido incorporado:

<!-- Allow all browsing contexts within this iframe to use fullscreen. -->
<iframe src="https://example.com..." allow="fullscreen"></iframe>

<!-- Equivalent to: -->
<iframe src="https://example.com..." allow="fullscreen *"></iframe>

<!-- Allow only iframe content on a particular origin to access the user's location. -->
<iframe
  src="https://another-example.com/demos/..."
  allow="geolocation https://another-example.com"
></iframe>

¿Qué ocurre con los atributos de iframe existentes?

Algunas de las funciones que controla la política de funciones tienen un atributo existente para controlar su comportamiento. Por ejemplo, <iframe allowfullscreen> es un atributo que permite que el contenido de iframe use la API de HTMLElement.requestFullscreen(). También existen los atributos allowpaymentrequest y allowusermedia para permitir la API de Payment Request y getUserMedia(), respectivamente.

Cuando sea posible, intenta usar el atributo allow en lugar de estos atributos anteriores. No hay ningún problema en los casos en los que necesites admitir la retrocompatibilidad mediante el atributo allow con un atributo heredado equivalente (p.ej., <iframe allowfullscreen allow="fullscreen">). Solo ten en cuenta que prevalecerá la política más restrictiva. Por ejemplo, el siguiente iframe no podría entrar en pantalla completa porque allow="fullscreen 'none'" es más restrictivo que allowfullscreen:

<!-- Blocks fullscreen access if the browser supports feature policy. -->
<iframe allowfullscreen allow="fullscreen 'none'" src="..."></iframe>

Cómo controlar varias políticas a la vez

Se pueden controlar varias funciones al mismo tiempo mediante el envío del encabezado HTTP con una lista de directivas de política separada por ;:

Feature-Policy: unsized-media 'none'; geolocation 'self' https://example.com; camera *;

o envía un encabezado independiente para cada política:

Feature-Policy: unsized-media 'none'
Feature-Policy: geolocation 'self' https://example.com
Feature-Policy: camera *;

En este ejemplo, se haría lo siguiente:

  • No permite el uso de unsized-media en todos los contextos de navegación.
  • No permite el uso de geolocation para todos los contextos de navegación, excepto para el origen y https://example.com de la página.
  • Permite el acceso de camera para todos los contextos de navegación.

Ejemplo: Configuración de varias políticas en un iframe

<!-- Blocks the iframe from using the camera and microphone
     (if the browser supports feature policy). -->
<iframe allow="camera 'none'; microphone 'none'"></iframe>

API de JavaScript

Si bien en Chrome 60 se agregó compatibilidad con el encabezado HTTP Feature-Policy y el atributo allow en los iframes, se agregó la API de JavaScript en Chrome 74.

Esta API permite que el código del cliente determine qué funciones están permitidas por una página, un marco o un navegador. Puedes acceder a sus accesorios en document.featurePolicy para el documento principal o en frame.featurePolicy para iframes.

Ejemplo

En el siguiente ejemplo, se ilustran los resultados de enviar una política de Feature-Policy: geolocation 'self' en el sitio https://example.com:

/* @return {Array<string>} List of feature policies allowed by the page. */
document.featurePolicy.allowedFeatures();
// → ["geolocation", "midi",  "camera", "usb", "autoplay",...]

/* @return {boolean} True if the page allows the 'geolocation' feature. */
document.featurePolicy.allowsFeature('geolocation');
// → true

/* @return {boolean} True if the provided origin allows the 'geolocation' feature. */
document.featurePolicy.allowsFeature(
  'geolocation',
  'https://another-example.com/'
);
// → false

/* @return {Array<string>} List of feature policies allowed by the browser
regardless of whether they are in force. */
document.featurePolicy.features();
// → ["geolocation", "midi",  "camera", "usb", "autoplay",...]

/* @return {Array<string>} List of origins (used throughout the page) that are
   allowed to use the 'geolocation' feature. */
document.featurePolicy.getAllowlistForFeature('geolocation');
// → ["https://example.com"]

Lista de políticas

¿Qué funciones se pueden controlar con la política de funciones?

En este momento, hay una falta de documentación sobre qué políticas se implementan y cómo usarlas. La lista también crecerá con el tiempo, a medida que diferentes navegadores adopten la especificación y diversas políticas. La política de funciones será un objetivo móvil y sin duda se necesitarán buenos documentos de referencia.

Por ahora, hay un par de formas de ver qué funciones se pueden controlar.

        ["geolocation",
         "midi",
         "camera",
         "usb",
         "magnetometer",
         "fullscreen",
         "animations",
         "payment",
         "picture-in-picture",
         "accelerometer",
         "vr",
        ...
  • Consulta chromestatus.com para ver las políticas que se implementaron o se están considerando en Blink.

Para determinar cómo usar algunas de estas políticas, consulta el repositorio de GitHub de la especificación. Contiene algunas explicaciones sobre algunas de las políticas.

Preguntas frecuentes

¿Cuándo debo usar la política de funciones?

Todas las políticas se habilitan, así que úsalas cuando y donde sea apropiado. Por ejemplo, si tu app es una galería de imágenes, la política maximum-downscaling-image te ayudaría a evitar el envío de imágenes gigantes a viewports de dispositivos móviles.

Debes usar otras políticas, como document-write y sync-xhr, con más cuidado. Si los activas, es posible que se generen daños en el contenido de terceros, como los anuncios. Por otro lado, la política de funciones puede ser una comprobación visceral para asegurarte de que tus páginas nunca usen estas APIs terribles.

¿Uso la política de funciones en el desarrollo o la producción?

Ambas. Te recomendamos activar las políticas durante el desarrollo y mantenerlas activas mientras se encuentran en la producción. Activar las políticas durante el desarrollo puede ayudarte a comenzar por el buen camino. Te ayudará a detectar cualquier regresión inesperada antes de que suceda. Mantén las políticas activadas en la producción para garantizar una UX determinada para los usuarios.

¿Hay alguna manera de denunciar incumplimientos de política a mi servidor?

Hay una API de Reporting en proceso en proceso. Así como los sitios pueden habilitar la recepción de informes sobre incumplimientos de la CSP o bajas, podrás recibir informes sobre incumplimientos de políticas de funciones sin problemas.

¿Cuáles son las reglas de herencia para el contenido iframe?

Las secuencias de comandos (propias o de terceros) heredan la política de su contexto de navegación. Esto significa que las secuencias de comandos de nivel superior heredan las políticas del documento principal.

Los elementos iframe heredan las políticas de su página superior. Si iframe tiene un atributo allow, prevalece la política más estricta entre la página superior y la lista de allow. Para obtener más información sobre el uso de iframe, consulta el atributo allow sobre iframes.

No. La vida útil de una política es para una sola respuesta de navegación de página. Si el usuario navega a una página nueva, el encabezado Feature-Policy debe enviarse de forma explícita en la respuesta nueva para que se aplique la política.

¿Qué navegadores admiten la política de funciones?

Visita caniuse.com para obtener los detalles más recientes sobre la compatibilidad del navegador.

A partir de ahora, Chrome es el único navegador compatible con la política de funciones. Sin embargo, como toda la plataforma de la API se puede habilitar o detectar, la política de funciones se adapta bien a la mejora progresiva.

Conclusión

La política de funciones puede ayudar a proporcionar un camino bien iluminado hacia una mejor UX y un buen rendimiento. Resulta muy útil cuando desarrollas o mantienes una app, ya que puede ayudar a evitar posibles armas de fuego antes de que se filtren en la base de código.

Recursos adicionales: