Introducción a la política de funciones

Resumen

La Política de funciones permite a los desarrolladores web habilitar, inhabilitar y modificar selectivamente 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í mismas son pequeños acuerdos de aceptación entre el desarrollador y el navegador que pueden ayudar a fomentar nuestros objetivos de crear (y mantener) aplicaciones web de alta calidad.

Introducción

Crear contenido para la Web es una aventura arriesgada. Es difícil compilar una app web de primer nivel que cumpla con el rendimiento y use todas las prácticas recomendadas más recientes. Es aún más difícil que la experiencia sea excelente con el tiempo. A medida que evoluciona tu proyecto, los desarrolladores se suman, se incorporan nuevas funciones y la base de código crece. Esa Gran experienciaTM que una vez lograste 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 en funciones específicas que se usan en todo tu sitio. Estas políticas restringen las APIs a las que el sitio puede acceder o modificar el comportamiento predeterminado del navegador para ciertas funciones.

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

  • Cambia el comportamiento predeterminado de autoplay en los videos para dispositivos móviles y de terceros.
  • Impedir que un sitio use APIs sensibles, como camera o microphone
  • Permite que los iframes usen la API de fullscreen.
  • Bloquea el uso de APIs desactualizadas como XHR síncronas 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 de que no sean demasiado grandes para el viewport (p.ej., desperdiciar el ancho de banda del usuario).

Las políticas son un contrato entre el desarrollador y el navegador. Informan al navegador sobre cuál es la intención del desarrollador y, por lo tanto, nos ayudan a mantenernos honestos cuando nuestra app intenta descarrilarse y hacer algo malo. Si el sitio o el contenido de terceros incorporado intenta infringir cualquiera de las reglas preseleccionadas del 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 quieres 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:

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

Ejemplo

Supongamos que quieres impedir que todo el contenido use la API de Geolocation en todo tu sitio. 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 de ubicación geográfica establecida
Incumplimiento de la política de ubicación geográfica establecida.

En otros casos, tendría sentido relajar un poco esta política. Podemos permitir que nuestro propio origen use la API de Geolocation, pero evitar que contenido de terceros acceda a ella. Para ello, configura 'self' en la lista de entidades permitidas:

Feature-Policy: geolocation 'self'

Atributo allow de iframe

La segunda forma de usar la política de funciones es controlar el contenido en una iframe. Usa el atributo allow a fin de 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 existentes del iframe?

Algunas de las funciones controladas por 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 HTMLElement.requestFullscreen(). También existen los atributos allowpaymentrequest y allowusermedia para permitir la API de Payment Request y getUserMedia(), respectivamente.

Intenta usar el atributo allow en lugar de estos atributos antiguos siempre que sea posible. En los casos en los que necesites admitir la retrocompatibilidad mediante el atributo allow con un atributo heredado equivalente, no hay problema (p.ej., <iframe allowfullscreen allow="fullscreen">). Solo ten en cuenta que gana la política más restrictiva. Por ejemplo, el siguiente iframe no podría entrar en el modo de 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>

Controla 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 bien enviando 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 propio de la página y https://example.com.
  • Permite el acceso de camera para todos los contextos de navegación.

Ejemplo: Establece 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 Chrome 60 agregó compatibilidad con el encabezado HTTP Feature-Policy y el atributo allow en iframes, la API de JavaScript se agregó en Chrome 74.

Esta API permite que el código del cliente determine qué funciones permite 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 muestran los resultados del envío de una política de Feature-Policy: geolocation 'self' al 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 los diferentes navegadores adopten la especificación y, luego, implementen varias políticas. La política de atributos será un destino en movimiento, y definitivamente se necesitarán buenos documentos de referencia.

Por ahora, existen varias formas de ver qué funciones se pueden controlar.

  • Consulta nuestras demostraciones sobre el fregadero de cocina de la política de funciones. Tiene ejemplos de cada política que se implementó en Blink.
  • Consulta la fuente de Chrome para ver la lista de nombres de las funciones.
  • Consulta document.featurePolicy.allowedFeatures() en about:blank para encontrar la lista:
        ["geolocation",
         "midi",
         "camera",
         "usb",
         "magnetometer",
         "fullscreen",
         "animations",
         "payment",
         "picture-in-picture",
         "accelerometer",
         "vr",
        ...
  • Consulta chromestatus.com para conocer las políticas que se implementaron o que 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 son opcionales, así que usa la Política de funciones cuando y donde sea pertinente. 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.

Se deben usar con más cuidado otras políticas, como document-write y sync-xhr. Si los activas, se podría dañar el contenido de terceros, como los anuncios. Por otro lado, la política de funciones puede ser una comprobación 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?

Ambos. Recomendamos activar las políticas durante el desarrollo y mantenerlas activas durante la producción. Activar las políticas durante el desarrollo puede ayudarte a comenzar con el buen camino. Te ayudará a detectar regresiones inesperadas antes de que sucedan. Mantén las políticas activadas en la producción para garantizar una UX determinada para los usuarios.

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

Una API de Reporting está 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 en el mundo real.

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

Las secuencias de comandos (propias o de terceros) heredan la política de su contexto de navegación. Eso 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, prevalecerá la política más estricta entre la página superior y la lista allow. Para obtener más información sobre el uso de iframe, consulta el atributo allow en iframes.

No. La vida útil de una política corresponde a una respuesta de navegación de una sola 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?

Consulta caniuse.com para obtener los detalles más recientes sobre la compatibilidad con navegadores.

Por el momento, Chrome es el único navegador que admite la política de funciones. Sin embargo, dado que se puede habilitar o detectar toda la superficie de la API, la política de funciones se presta muy bien a la mejora progresiva.

Conclusión

La política de funciones puede ayudar a proporcionar un camino bien iluminado para lograr una mejor UX y un buen rendimiento. Es especialmente útil cuando se desarrolla o mantiene una app, ya que puede ayudar a evitar posibles pistolas de pie antes de que se filtren en tu base de código.

Recursos adicionales: