Introducción a la política de funciones

Resumen

La política de funciones permite a los desarrolladores web habilitar, inhabilitar y modificar de forma selectiva el comportamiento de ciertas APIs y funciones web en el navegador. Es como un 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 compilar (y mantener) apps web de alta calidad.

Introducción

Crear para la Web es una aventura difícil. Ya es bastante difícil compilar una app web de primer nivel que tenga un rendimiento excelente y que use todas las prácticas recomendadas más recientes. Es aún más difícil mantener esa experiencia excelente con el tiempo. A medida que tu proyecto evoluciona, se incorporan desarrolladores, se lanzan nuevas funciones y crece la base de código. Es posible que esa gran experiencia ™ que lograste en algún momento comience a deteriorarse y la UX empiece a sufrir. La Política de funciones está diseñada para ayudarte a mantenerte en el camino correcto.

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

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

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

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

Usa 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 los iframes.

La forma más sencilla de usar Feature Policy 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 anidados del mismo origen. No se permite en documentos de origen cruzado en contextos de navegación anidados.
  • 'none': La función no se permite en contextos de navegación de nivel superior ni en contextos de navegación anidados.
  • <origin(s)>: Son los orígenes específicos para los que se habilita la política (p.ej., https://example.com).

Ejemplo

Supongamos que quieres bloquear todo el contenido para que no use la API de Geolocation en 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 un iframe intenta usar la API de Geolocation, el navegador lo bloquea. Esto sucede incluso si el usuario ya otorgó permiso para compartir su ubicación.

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

En otros casos, podría ser conveniente flexibilizar un poco esta política. Podemos permitir que nuestro propio origen use la API de Geolocation, pero evitar que el contenido de terceros acceda a ella configurando 'self' en la lista de entidades permitidas:

Feature-Policy: geolocation 'self'

El atributo allow del iframe

La segunda forma de usar la Política de funciones es para controlar el contenido dentro de un 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é sucede con los atributos de iframe existentes?

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 de HTMLElement.requestFullscreen(). También están 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 que necesites admitir la compatibilidad con versiones anteriores, usar el atributo allow con un atributo heredado equivalente es perfectamente aceptable (p.ej., <iframe allowfullscreen allow="fullscreen">). Ten en cuenta que se aplica la política más restrictiva. Por ejemplo, al siguiente iframe no se le permitiría ingresar al 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>

Cómo controlar varias políticas a la vez

Se pueden controlar varias funciones al mismo tiempo enviando el encabezado HTTP con una lista de directivas de políticas separadas por ;:

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

o 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 realizarían las siguientes acciones:

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

Ejemplo: Cómo configurar 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 los 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 elementos en document.featurePolicy para el documento principal o en frame.featurePolicy para los 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

Entonces, ¿qué funciones se pueden controlar a través de la política de funciones?

En este momento, falta 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 apliquen varias políticas. La política de funciones será un objetivo en constante movimiento, y definitivamente se necesitarán documentos de referencia de calidad.

Por ahora, existen dos maneras de ver qué funciones se pueden controlar.

  • Consulta nuestro Kitchen Sink de la Política de funciones de demostraciones. Tiene ejemplos de cada política que se implementó en Blink.
  • Consulta la fuente de Chrome para ver la lista de nombres de 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 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 son de solicitud de aceptación, por lo que debes usar la Política de funciones cuando y donde sea conveniente. Por ejemplo, si tu app es una galería de imágenes, la política de maximum-downscaling-image te ayudaría a evitar enviar imágenes gigantescas a los viewports para dispositivos móviles.

Otras políticas, como document-write y sync-xhr, deben usarse con más cuidado. Si los activas, es posible que se dañe el contenido de terceros, como los anuncios. Por otro lado, la política de funciones puede ser una herramienta de validación para asegurarte de que tus páginas nunca usen estas APIs terribles.

¿Debo usar la Política de funciones en desarrollo o en producción?

Ambas. Te recomendamos que actives las políticas durante el desarrollo y las mantengas activas durante la producción. Activar las políticas durante el desarrollo puede ayudarte a comenzar de la manera correcta. Te ayudará a detectar cualquier regresión inesperada antes de que ocurra. Mantén las políticas activadas en producción para garantizar una UX determinada para los usuarios.

¿Existe alguna forma de denunciar incumplimientos de políticas a mi servidor?

Estamos trabajando en una API de informes. Al igual que los sitios pueden habilitar la recepción de informes sobre incumplimientos de CSP o bajas, podrás recibir informes sobre incumplimientos de la política de funciones en el campo.

¿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. Esto significa que las secuencias de comandos de nivel superior heredan las políticas del documento principal.

Los iframe heredan las políticas de su página superior. Si el 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 es para una respuesta de navegación de una sola página. Si el usuario navega a una página nueva, el encabezado Feature-Policy se debe enviar 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.

Actualmente, Chrome es el único navegador que admite la política de funciones. Sin embargo, como toda la plataforma de la API es de solicitud de aceptación o detectable por funciones, la política de funciones se adapta muy bien a la mejora progresiva.

Conclusión

La Política de funciones puede ayudarte a proporcionar una ruta bien iluminada hacia una mejor UX y un buen rendimiento. Es especialmente útil cuando se desarrolla o se mantiene una app, ya que puede ayudar a evitar posibles errores antes de que se infiltren en tu base de código.

Recursos adicionales: