Présentation des règles relatives aux caractéristiques

Eric Bidelman

Résumé

Les règles relatives aux fonctionnalités permettent aux développeurs Web d'activer, de désactiver et de modifier de manière sélective le comportement de certaines API et fonctionnalités Web dans le navigateur. Semblable à CSP, mais au lieu de contrôler la sécurité, il contrôle les fonctionnalités.

Les règles de fonctionnalité elles-mêmes constituent de petits accords d'acceptation entre le développeur et le navigateur qui peuvent nous aider à soutenir nos objectifs de création (et de maintenance) d'applications Web de haute qualité.

Introduction

Construire pour le Web est une aventure rocailleuse. Créer une application Web de qualité, qui optimise les performances et applique les bonnes pratiques les plus récentes, est suffisamment difficile. Il est encore plus difficile d'améliorer cette expérience au fil du temps. À mesure que votre projet évolue, les développeurs s'en chargent, de nouvelles fonctionnalités arrivent et le codebase s'agrandit. Cette expérience exceptionnelle peut commencer à se détériorer et à nuire à l'expérience utilisateur. Les règles sur les fonctionnalités sont conçues pour vous aider à garder le cap.

Avec les règles pour les fonctionnalités, vous activez un ensemble de "règles" pour le navigateur afin d'appliquer des fonctionnalités spécifiques utilisées sur votre site. Ces règles limitent les API auxquelles le site peut accéder ou modifient le comportement par défaut du navigateur pour certaines fonctionnalités.

Voici quelques exemples de ce que vous pouvez faire avec les règles pour les caractéristiques:

  • Modifiez le comportement par défaut de autoplay sur les vidéos mobiles et tierces.
  • Empêchez un site d'utiliser des API sensibles comme camera ou microphone.
  • Autoriser les iFrame à utiliser l'API fullscreen.
  • Bloquez l'utilisation d'API obsolètes telles que XHR synchrones et document.write().
  • Assurez-vous que les images sont correctement dimensionnées (par exemple, pour éviter le thrashing) et qu'elles ne sont pas trop grandes pour la fenêtre d'affichage (par exemple, elles gaspillent la bande passante de l'utilisateur).

Les règles sont un contrat entre le développeur et le navigateur. Elles informent le navigateur de l'intention du développeur et nous aident ainsi à être honnêtes lorsque notre application tente de déraper et de faire quelque chose de mal. Si le site ou le contenu tiers intégré tente d'enfreindre l'une des règles présélectionnées par le développeur, le navigateur remplace le comportement par une meilleure expérience utilisateur ou bloque complètement l'API.

Utiliser une règle de caractéristiques

Les règles relatives aux caractéristiques permettent de contrôler les fonctionnalités de deux façons:

  1. Via l'en-tête HTTP Feature-Policy
  2. Avec l'attribut allow sur les cadres iFrame.

Le moyen le plus simple d'utiliser une règle de caractéristiques consiste à envoyer l'en-tête HTTP Feature-Policy avec la réponse d'une page. La valeur de cet en-tête est une règle ou un ensemble de règles que vous souhaitez que le navigateur respecte pour une origine donnée:

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

La liste d'autorisation des origines peut prendre plusieurs valeurs différentes:

  • *: cette fonctionnalité est autorisée dans les contextes de navigation de premier niveau et dans les contextes de navigation imbriqués (iFrame).
  • 'self': cette fonctionnalité est autorisée dans les contextes de navigation de premier niveau et les contextes de navigation imbriqués de même origine. Elle n'est pas autorisée dans les documents multi-origines dans les contextes de navigation imbriqués.
  • 'none': cette fonctionnalité n'est pas autorisée dans les contextes de navigation de premier niveau ni dans les contextes de navigation imbriqués.
  • <origin(s)>: origines spécifiques pour lesquelles la règle doit être activée (par exemple, https://example.com).

Exemple

Supposons que vous souhaitiez empêcher l'utilisation de l'API Geolocation pour tous les contenus de votre site. Pour ce faire, envoyez une liste d'autorisation stricte de 'none' pour la fonctionnalité geolocation:

Feature-Policy: geolocation 'none'

Si un extrait de code ou un iFrame tente d'utiliser l'API Geolocation, le navigateur le bloque. Cela est vrai même si l'utilisateur a déjà autorisé le partage de sa position.

Non-respect des règles de géolocalisation définies
Non-respect de la règle de géolocalisation définie.

Dans d'autres cas, il peut être judicieux d'assouplir un peu cette stratégie. Nous pouvons autoriser notre propre origine à utiliser l'API Geolocation, mais empêcher le contenu tiers d'y accéder en définissant 'self' dans la liste d'autorisation:

Feature-Policy: geolocation 'self'

Attribut iFrame allow

La deuxième façon d'utiliser une règle de caractéristiques consiste à contrôler le contenu au sein d'une iframe. Utilisez l'attribut allow afin de spécifier une liste de règles pour le contenu intégré:

<!-- 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'en est-il des attributs iFrame existants ?

Certaines fonctionnalités contrôlées par une règle de fonctionnalité disposent d'un attribut pour contrôler leur comportement. Par exemple, <iframe allowfullscreen> est un attribut qui permet au contenu iFrame d'utiliser l'API HTMLElement.requestFullscreen(). Les attributs allowpaymentrequest et allowusermedia permettent également d'autoriser l'API Payment Request et getUserMedia(), respectivement.

Dans la mesure du possible, essayez d'utiliser l'attribut allow au lieu de ces anciens attributs. Dans les cas où vous devez assurer la rétrocompatibilité avec l'attribut allow avec un ancien attribut équivalent (par exemple, <iframe allowfullscreen allow="fullscreen">), notez que la règle la plus restrictive l'emporte. Par exemple, l'iFrame suivant ne serait pas autorisé à passer en plein écran, car allow="fullscreen 'none'" est plus restrictif que allowfullscreen:

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

Contrôler plusieurs règles à la fois

Vous pouvez contrôler plusieurs fonctionnalités en même temps en envoyant l'en-tête HTTP avec une liste d'instructions de règle séparées par ;:

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

ou en envoyant un en-tête distinct pour chaque stratégie:

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

Cet exemple présente le code suivant:

  • Interdit l'utilisation de unsized-media pour tous les contextes de navigation.
  • Interdit l'utilisation de geolocation pour tous les contextes de navigation, à l'exception de la propre origine de la page et de https://example.com.
  • Autorise l'accès à camera pour tous les contextes de navigation.

Exemple : Définir plusieurs règles sur 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 JavaScript

Alors que Chrome 60 accepte l'en-tête HTTP Feature-Policy et l'attribut allow sur les iFrames, l'API JavaScript a été ajoutée dans Chrome 74.

Cette API permet au code côté client de déterminer les fonctionnalités autorisées par une page, un frame ou un navigateur. Vous pouvez accéder à ses goodies sous document.featurePolicy pour le document principal ou frame.featurePolicy pour les cadres iFrame.

Exemple

L'exemple ci-dessous illustre les résultats de l'envoi d'une règle Feature-Policy: geolocation 'self' sur le site 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"]

Liste des règles

Quelles fonctionnalités peuvent être contrôlées via les règles de fonctionnalité ?

À l'heure actuelle, il manque de documentation sur les règles mises en œuvre et sur leur utilisation. Cette liste s'allonge également au fil du temps, à mesure que différents navigateurs adoptent les spécifications et appliquent différentes règles. Les règles de caractéristiques vont constituer une cible mouvante, et de bonnes documents de référence seront certainement nécessaires.

Pour l'instant, il existe plusieurs façons de voir quelles fonctionnalités sont contrôlables.

  • Consultez nos démos sur notre Évier de cuisine. Elle contient des exemples de chaque règle implémentée dans Blink.
  • Consultez le code source de Chrome pour obtenir la liste des noms de fonctionnalités.
  • Interrogez document.featurePolicy.allowedFeatures() sur about:blank pour trouver la liste:
        ["geolocation",
         "midi",
         "camera",
         "usb",
         "magnetometer",
         "fullscreen",
         "animations",
         "payment",
         "picture-in-picture",
         "accelerometer",
         "vr",
        ...
  • Consultez chromestatus.com pour connaître les règles qui ont été implémentées ou qui sont envisagées dans Blink.

Pour savoir comment utiliser certaines de ces stratégies, consultez le dépôt GitHub des spécifications. Elle contient quelques explications sur certaines des règles.

Questions fréquentes

Quand utiliser une règle de fonctionnalité ?

Toutes les règles étant facultatives, vous devez utiliser les règles de fonctionnalité lorsque cela est pertinent. Par exemple, si votre application est une galerie d'images, la règle maximum-downscaling-image vous évitera d'envoyer des images gigantesques aux fenêtres d'affichage mobile.

Les autres règles telles que document-write et sync-xhr doivent être utilisées avec plus de prudence. Si vous les activez, le contenu tiers tel que les annonces risquerait d'être endommagé. En revanche, les règles de fonctionnalité peuvent vous aider à vérifier que vos pages n'utilisent jamais ces horribles API.

Dois-je utiliser l'API Feature Policy en phase de développement ou de production ?

les deux. Nous vous recommandons d'activer les règles pendant le développement et de les garder actives en production. L'activation des règles pendant le développement peut vous aider à démarrer sur la bonne voie. Cela vous aidera à détecter toutes les régressions inattendues avant qu'elles ne se produisent. Laissez les règles activées en production pour garantir une certaine expérience utilisateur aux utilisateurs.

Existe-t-il un moyen de signaler les cas de non-respect des règles à mon serveur ?

Une API Reporting est en préparation. De la même manière que les sites peuvent choisir de recevoir des rapports sur les cas de non-respect des règles de CSP ou les abandons, vous pourrez recevoir des rapports sur les cas de non-respect des règles de caractéristiques dans la nature.

Quelles sont les règles d'héritage pour le contenu iFrame ?

Les scripts (propriétaires ou tiers) héritent de la règle de leur contexte de navigation. Cela signifie que les scripts de premier niveau héritent des stratégies du document principal.

Les éléments iframe héritent des règles de leur page parente. Si iframe comporte un attribut allow, la règle la plus stricte entre la page parente et la liste allow l'emporte. Pour en savoir plus sur l'utilisation de iframe, consultez l'attribut allow sur les iFrames.

Non. La durée de vie d'une règle correspond à une réponse de navigation sur une seule page. Si l'utilisateur accède à une nouvelle page, l'en-tête Feature-Policy doit être explicitement envoyé dans la nouvelle réponse pour que la stratégie s'applique.

Quels sont les navigateurs compatibles avec Feature Policy ?

Consultez caniuse.com pour en savoir plus sur les navigateurs compatibles.

À l'heure actuelle, Chrome est le seul navigateur compatible avec les règles de fonctionnalités. Cependant, étant donné que l'ensemble de la surface de l'API est activé ou détectable des caractéristiques, les règles de caractéristiques se prêtent parfaitement à une amélioration progressive.

Conclusion

Les règles de fonctionnalité peuvent contribuer à améliorer l'expérience utilisateur et les performances. Cette approche est particulièrement utile lors du développement ou de la maintenance d'une application, car elle permet d'éviter d'éventuels pistolets avant qu'ils ne s'infiltrent dans votre codebase.

Autres ressources