Pourquoi avez-vous besoin d'un modèle isolé multi-origine pour bénéficier de fonctionnalités performantes ?

Publié le 4 mai 2020

Dans Rendre votre site Web "isolé multi-origine" à l'aide de COOP et COEP nous avons expliqué comment adopter l'état "isolé multi-origine" à l'aide de COOP et COEP. Cet article complémentaire explique pourquoi l'isolation multi-origine est nécessaire pour activer des fonctionnalités puissantes dans le navigateur.

Glossaire

Ce document utilise de nombreux termes et abréviations aux noms similaires. Pour plus de clarté, nous avons créé un mini-glossaire :

Arrière-plan

Le Web repose sur la règle d'origine commune, une fonctionnalité de sécurité qui limite la façon dont les documents et les scripts peuvent interagir avec les ressources d'une autre origine. Ce principe limite la façon dont les sites Web peuvent accéder aux ressources interorigines. Par exemple, un document provenant de https://a.example ne peut pas accéder aux données hébergées sur https://b.example.

Toutefois, la règle d'origine commune a connu quelques exceptions historiques. N'importe quel site Web peut :

  • intégrer des iFrame interorigines
  • inclure des ressources interorigines telles que des images ou des scripts ;
  • ouvrir des fenêtres de dialogue interorigines avec une référence DOM.

Lorsque la communauté Web a pris conscience des avantages d'une règle d'origine commune stricte, le Web reposait déjà sur ces exceptions.

Les effets secondaires de sécurité d'une règle d'origine commune aussi laxiste ont été corrigés de deux manières :

  • Le protocole CORS (Cross Origin Resource Sharing) s'assure que le serveur autorise le partage d'une ressource avec une origine donnée.
  • Les développeurs suppriment implicitement l'accès direct aux scripts pour les ressources interorigines, tout en préservant la rétrocompatibilité. Ces ressources interorigines sont appelées ressources "opaques". C'est pourquoi la manipulation de pixels interorigines avec CanvasRenderingContext2D échoue, sauf si CORS est appliqué à l'image.

Toutes ces décisions concernant les règles sont prises dans un groupe de contexte de navigation.

Le groupe de contexte de navigation inclut le site principal et les composants du site intégré.

Pendant longtemps, cette combinaison a suffi à assurer la sécurité des navigateurs, avec des cas extrêmes limités qui nécessitaient une correction directe (comme les failles JSON).

Cela a changé avec Spectre, qui rend potentiellement lisibles toutes les données chargées dans le même groupe de contexte de navigation que votre code. En mesurant le temps nécessaire à certaines opérations, les pirates peuvent deviner le contenu des caches du processeur, et donc le contenu de la mémoire du processus. De telles attaques sont possibles avec des minuteurs à faible granularité qui existent dans la plate-forme, et peuvent être accélérées avec des minuteurs à haute granularité, à la fois explicites (comme performance.now()) et implicites (comme SharedArrayBuffers).

Si evil.com intègre une image multi-origine, il peut utiliser une attaque Spectre pour lire les données de pixels de l'image intégrée. Cela rend inefficaces les protections qui reposent sur l'"opacité".

Evil.com est le site Web principal qui attaque l'iFrame et les images b.example intégrés à l'aide de Spectre.

Idéalement, toutes les requêtes interorigines sont examinées par le serveur propriétaire de la ressource. Si l'examen n'a pas été effectué, les données ne doivent jamais atteindre le groupe de contexte de navigation d'un acteur malveillant. Ainsi, les données restent hors de portée des attaques Spectre possibles. Nous appelons cela un état isolé multi-origine.

Lorsque le code intégré est dans un état isolé multi-origine, le site demandeur est considéré comme moins dangereux. Cela permet au site demandeur d'utiliser SharedArrayBuffer, performance.measureUserAgentSpecificMemory() et des minuteurs haute résolution avec une meilleure précision, tout en empêchant les attaques Spectre possibles. Cet état empêche également la modification de document.domain.

Règlement de l'intégrateur multi-origine

Le règlement de l'intégrateur interorigine (COEP, Cross Origin Embedder Policy) empêche un document de charger des ressources interorigines qui n'accordent pas explicitement l'autorisation au document avec CORP ou CORS. Grâce à cette fonctionnalité, vous pouvez déclarer qu'un document ne peut pas charger de telles ressources.

Diagramme des composants intégrés autorisés et non autorisés, grâce aux règles CORP.
Le site parent, a.example, a défini la règle COEP sur require-corp. a.example souhaite intégrer trois éléments de b.example, mais seuls deux réussissent. Les deux intégrations réussies incluent un fichier JavaScript avec une règle CORP interorigine et une image avec CORS autorisé. Le troisième élément est une vidéo dont la règle CORP exige qu'elle soit intégrée uniquement sur la même origine. Par conséquent, la vidéo ne sera pas chargée sur a.example.

Pour activer cette règle, ajoutez l'en-tête HTTP suivant au document :

Cross-Origin-Embedder-Policy: require-corp

COEP prend une seule valeur de require-corp. Cela applique la règle selon laquelle le document ne peut charger que des ressources de la même origine ou des ressources explicitement marquées comme pouvant être chargées à partir d'une autre origine.

Pour que les ressources puissent être chargées à partir d'une autre origine, elles doivent être compatibles avec le partage des ressources entre origines multiples (CORS) ou la règle de ressource multi-origine (CORP).

Partage des ressources entre origines multiples

Si une ressource multi-origine est compatible avec le partage des ressources entre origines multiples (CORS), vous pouvez utiliser l' crossorigin attribut pour la charger sur votre page Web sans être bloqué par COEP.

<img src="https://third-party.example.com/image.jpg" crossorigin>

Par exemple, si cette ressource d'image est diffusée avec des en-têtes CORS, utilisez l' crossorigin attribut pour que la requête permettant de récupérer la ressource utilise le mode CORS. Cela empêche également le chargement de l'image, sauf si elle définit des en-têtes CORS.

De même, vous pouvez récupérer des données multi-origines via la méthode fetch(), qui ne nécessite pas de traitement spécial tant que le serveur répond avec les bons en-têtes HTTP.

Règle de ressource multi-origine

La règle de ressource multi-origine (CORP, Cross Origin Resource Policy) a été initialement introduite comme une option permettant de protéger vos ressources contre le chargement par une autre origine. Dans le contexte de COEP, CORP peut spécifier la règle du propriétaire de la ressource concernant les personnes autorisées à charger une ressource.

L'en-tête Cross-Origin-Resource-Policy accepte trois valeurs possibles :

Cross-Origin-Resource-Policy: same-site

Les ressources marquées same-site ne peuvent être chargées qu'à partir du même site.

Cross-Origin-Resource-Policy: same-origin

Les ressources marquées same-origin ne peuvent être chargées qu'à partir de la même origine.

Cross-Origin-Resource-Policy: cross-origin

Les ressources marquées cross-origin peuvent être chargées par n'importe quel site Web. (Cette valeur a été ajoutée à la spécification CORP avec COEP.)

Règle d'ouverture multi-origine

La règle d'ouverture multi-origine (COOP, Cross Origin Opener Policy) vous permet d'isoler une fenêtre de premier niveau des autres documents en plaçant les documents dans un groupe de contexte de navigation distinct. Ainsi, les documents ne peuvent pas interagir directement avec la fenêtre de premier niveau. Par exemple, si un document avec COOP ouvre une boîte de dialogue, sa propriété window.opener est null. La propriété .closed de la référence de l'ouvreur est true.

a.example n'a pas pu ouvrir b.example dans une boîte de dialogue.

L'en-tête Cross-Origin-Opener-Policy accepte trois valeurs possibles :

Cross-Origin-Opener-Policy: same-origin

Les documents marqués same-origin peuvent partager le même groupe de contexte de navigation avec les documents de même origine qui sont également explicitement marqués same-origin.

Dessin représentant une fenêtre capable d 'interagir avec un pop-up &quot;same-origin&quot; qui se trouve dans le même groupe de contexte de navigation, mais pas avec un pop-up &quot;same-origin&quot; qui se trouve toujours en dehors du groupe de contexte de navigation.

Cross-Origin-Opener-Policy: same-origin-allow-popups

Un document de premier niveau avec same-origin-allow-popups conserve les références à toutes ses pop-ups qui ne définissent pas COOP ou qui désactivent l'isolation en définissant un COOP de unsafe-none.

COOP

Cross-Origin-Opener-Policy: unsafe-none

unsafe-none est la valeur par défaut et permet d'ajouter le document au groupe de contexte de navigation de son ouvreur, sauf si l'ouvreur lui-même a un COOP de same-origin.

Résumé

Si vous souhaitez accéder à des fonctionnalités telles que SharedArrayBuffer, performance.measureUserAgentSpecificMemory(), ou des minuteurs haute résolution avec une meilleure précision, votre document doit utiliser à la fois COEP avec la valeur require-corp et COOP avec la valeur same-origin. En l'absence de l'un ou l'autre, le navigateur ne garantit pas une isolation suffisante pour activer en toute sécurité ces fonctionnalités puissantes. Vous pouvez déterminer la situation de votre page en vérifiant si self.crossOriginIsolated renvoie true.

Découvrez comment implémenter cela dans Rendre votre site Web "isolé multi-origine quot; à l'aide de COOP et COEP.

Ressources