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

Découvrez pourquoi l'isolation multi-origine est nécessaire pour utiliser des fonctionnalités puissantes telles que SharedArrayBuffer, performance.measureUserAgentSpecificMemory() et le minuteur haute résolution avec une meilleure précision.

Introduction

Dans Rendre votre site Web "cross-origin isolated" à l'aide de COOP et COEP, nous avons expliqué comment adopter l'état "cross-origin isolated" à 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.

Arrière-plan

Le Web repose sur le règlement d'origine identique, 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 d'origines croisées. 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 identique a connu quelques exceptions historiques. Tout site Web peut :

  • Intégrer des iFrames multi-origines
  • Inclure des ressources d'origine croisée telles que des images ou des scripts
  • Ouvrir des fenêtres pop-up cross-origin avec une référence DOM

Si le Web pouvait être conçu à partir de zéro, ces exceptions n'existeraient pas. Malheureusement, lorsque la communauté Web a pris conscience des principaux avantages d'une règle d'origine identique stricte, le Web s'appuyait déjà sur ces exceptions.

Les effets secondaires de sécurité d'une règle d'origine identique aussi laxiste ont été corrigés de deux manières. L'une d'elles consistait à introduire un nouveau protocole appelé Cross-Origin Resource Sharing (CORS), dont l'objectif est de s'assurer que le serveur autorise le partage d'une ressource avec une origine donnée. L'autre méthode consiste à supprimer implicitement l'accès direct des scripts aux ressources d'origine croisée tout en préservant la rétrocompatibilité. Ces ressources d'origine croisée sont appelées ressources "opaques". Par exemple, c'est pourquoi la manipulation des pixels d'une image multi-origine via CanvasRenderingContext2D échoue, sauf si CORS est appliqué à l'image.

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

Groupe de contexte de navigation

Pendant longtemps, la combinaison de CORS et de ressources opaques a suffi à sécuriser les navigateurs. Des cas extrêmes (tels que les failles JSON) ont parfois été découverts et ont dû être corrigés, mais dans l'ensemble, le principe de ne pas autoriser l'accès en lecture direct aux octets bruts des ressources d'origine croisée a été efficace.

Tout 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 informatiques peuvent deviner le contenu des caches du processeur et, par conséquent, le contenu de la mémoire du processus. De telles attaques de timing sont possibles avec les minuteurs à faible précision qui existent dans la plate-forme, mais peuvent être accélérées avec des minuteurs à haute précision, à la fois explicites (comme performance.now()) et implicites (comme SharedArrayBuffers). Si evil.com intègre une image d'origine croisée, il peut utiliser une attaque Spectre pour lire ses données de pixels, ce qui rend inefficaces les protections reposant sur l'"opacité".

Spectr

Dans l'idéal, toutes les requêtes cross-origin doivent être explicitement examinées par le serveur propriétaire de la ressource. Si la validation n'est pas fournie par le serveur propriétaire de la ressource, les données n'atteindront jamais le groupe de contexte de navigation d'un acteur malveillant et resteront donc hors de portée de toute attaque Spectre qu'une page Web pourrait effectuer. Nous l'appelons un état isolé multi-origine. C'est exactement ce que font COOP+COEP.

Dans un état d'isolation multi-origine, le site demandeur est considéré comme moins dangereux. Cela permet de débloquer des fonctionnalités puissantes telles que SharedArrayBuffer, performance.measureUserAgentSpecificMemory() et les timers haute résolution avec une meilleure précision, qui pourraient autrement être utilisés pour des attaques de type Spectre. Cela empêche également la modification de document.domain.

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

La Cross-Origin Embedder Policy (COEP) empêche un document de charger des ressources d'origines multiples qui n'accordent pas explicitement l'autorisation au document (à l'aide de CORP ou CORS). Cette fonctionnalité vous permet de déclarer qu'un document ne peut pas charger de telles ressources.

Fonctionnement de COEP

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

Cross-Origin-Embedder-Policy: require-corp

COEP accepte une seule valeur : 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 inter-origines (CORS) ou la stratégie de ressources inter-origines (CORP).

Partage des ressources entre origines multiples

Si une ressource d'origine croisée est compatible avec le partage de ressources entre origines multiples (CORS), vous pouvez utiliser l'attribut crossorigin 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'attribut crossorigin afin 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 d'origine croisée à l'aide de 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èglement sur le partage de ressources entre origines

La stratégie de partage des ressources entre origines multiples (CORP, Cross-Origin Resource Policy) a été initialement introduite en tant qu'option pour protéger vos ressources contre le chargement par une autre origine. Dans le contexte de COEP, CORP peut spécifier la stratégie du propriétaire de la ressource concernant les personnes autorisées à charger une ressource.

L'en-tête Cross-Origin-Resource-Policy peut prendre trois valeurs :

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 en même temps que COEP.)

Règle d'ouverture multi-origine

La Cross-Origin Opener Policy (COOP) vous permet de vous assurer qu'une fenêtre de premier niveau est isolée des autres documents en les plaçant dans un groupe de contexte de navigation différent, de sorte qu'ils ne puissent pas interagir directement avec la fenêtre de premier niveau. Par exemple, si un document avec COOP ouvre un pop-up, sa propriété window.opener sera null. De plus, la propriété .closed de la référence de l'ouvreur à celui-ci renverra true.

COOP

L'en-tête Cross-Origin-Opener-Policy peut prendre trois valeurs :

Cross-Origin-Opener-Policy: same-origin

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

COOP

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 fenêtres pop-up qui ne définissent pas de COOP ou qui désactivent l'isolation en définissant une 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 une valeur COOP de same-origin.

Résumé

Si vous souhaitez bénéficier d'un accès garanti à des fonctionnalités puissantes telles que SharedArrayBuffer, performance.measureUserAgentSpecificMemory() ou les timers haute résolution avec une meilleure précision, n'oubliez pas que 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 ces fonctionnalités puissantes en toute sécurité. Vous pouvez déterminer la situation de votre page en vérifiant si self.crossOriginIsolated renvoie true.

Pour savoir comment implémenter cette fonctionnalité, consultez Rendre votre site Web "cross-origin isolated" (isolation multi-origine) à l'aide de COOP et COEP.

Ressources