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.

Dans Faire en sorte que votre site Web soit "isolé entre origines" à l'aide de COOP et COEP, nous avons expliqué comment adopter l'état "isolé entre origines" à 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.

Contexte

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 les moyens dont les sites Web peuvent accéder aux ressources multi-origines. Par exemple, un document de https://a.example est empêché d'accéder aux données hébergées sur https://b.example.

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

  • Intégrer des iFrame inter-origines
  • Inclure des ressources multi-origines telles que des images ou des scripts
  • Ouvrir des fenêtres pop-up inter-origines avec une référence DOM

Si le Web pouvait être conçu à partir de zéro, ces exceptions n'existeraient pas. Malheureusement, au moment où la communauté Web a réalisé les principaux avantages d'une règle stricte sur le même domaine, le Web s'appuyait déjà sur ces exceptions.

Les effets secondaires de sécurité d'une telle règle d'origine identique laxiste ont été corrigés de deux manières. L'une des solutions a été l'introduction d'un nouveau protocole appelé Cross-Origin Resource Sharing (CORS), qui a pour but 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 multi-origines tout en préservant la rétrocompatibilité. Ces ressources multi-origines 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 de règles se produisent dans un groupe de contexte de navigation.

Groupe de contexte de navigation

Pendant longtemps, la combinaison de CORS et de ressources opaques suffisait à sécuriser les navigateurs. Parfois, des cas particuliers (tels que des vulnérabilités JSON) ont été découverts et ont dû être corrigés, mais dans l'ensemble, le principe consistant à ne pas autoriser l'accès en lecture direct aux octets bruts des ressources multi-origines 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 que prennent certaines opérations, les pirates informatiques peuvent deviner le contenu des caches de processeur, et par conséquent, le contenu de la mémoire du processus. De telles attaques par cassage de chiffrement sont possibles avec les minuteurs à faible granularité de la plate-forme, mais peuvent être accélérées avec des minuteurs à haute granularité, à la fois explicites (comme performance.now()) et implicites (comme les SharedArrayBuffer). Si evil.com intègre une image inter-origine, il peut utiliser une attaque Spectre pour lire ses données de pixel, ce qui rend les protections reposant sur l'"opacité" inefficaces.

Spectr

Dans l'idéal, toutes les requêtes inter-origines doivent être examinées explicitement par le serveur propriétaire de la ressource. Si le serveur propriétaire des ressources ne fournit pas de vérification, les données ne rejoindront 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 appelons cela un état isolé multi-origine. C'est exactement ce que COOP+COEP vise à faire.

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

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

La règle d'intégration inter-origines (COEP, Cross Origin Embedder Policy) empêche un document de charger des ressources inter-origines qui n'accordent pas explicitement l'autorisation au document (à l'aide de CORP ou de CORS). Grâce à cette fonctionnalité, vous pouvez déclarer qu'un document ne peut pas charger de telles ressources.

Fonctionnement du COEP

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

Cross-Origin-Embedder-Policy: require-corp

COEP n'accepte qu'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 de ressources inter-origines (CORS) ou le protocole CORP (Cross Origin Resource Policy).

Cross Origin Resource Sharing

Si une ressource inter-origine 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 de récupération de la ressource utilise le mode CORS. Cela empêche également le chargement de l'image, sauf s'il définit des en-têtes CORS.

De même, vous pouvez extraire 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 en-têtes HTTP appropriés.

Cross-Origin Resource Policy

La Cross-Origin Resource Policy (CORP) a été initialement introduite comme une fonctionnalité activable 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 pour déterminer qui peut 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 que depuis le 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 COOP (Cross Origin Opener Policy) vous permet de vous assurer qu'une fenêtre de niveau supérieur est isolée des autres documents en les plaçant dans un groupe de contexte de navigation différent, afin qu'ils ne puissent pas interagir directement avec la fenêtre de niveau supérieur. 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'ouvre-boîte y 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 avec les documents de même origine qui sont également marqués explicitement same-origin.

COOP

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

Un document de niveau supérieur avec same-origin-allow-popups conserve les références à tous ses pop-ups qui ne définissent pas de COOP ou qui désactivent l'isolation en définissant une valeur 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 ouvre-fichier, sauf si l'ouvre-fichier lui-même a une valeur COOP de same-origin.

Résumé

Si vous souhaitez un accès garanti à des fonctionnalités puissantes telles que SharedArrayBuffer, performance.measureUserAgentSpecificMemory() ou les minuteurs 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 de 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 procéder, consultez Isoler votre site Web de manière inter-origine à l'aide de COOP et COEP.

Ressources