Isolation de sites pour les développeurs Web

Chrome 67 sur ordinateur dispose d'une nouvelle fonctionnalité appelée Isolation de sites activée par défaut. Ce explique en quoi consiste l'isolation de sites, pourquoi elle est nécessaire et pourquoi les développeurs Web devraient n'en soyez pas conscient.

Qu'est-ce que l'isolation de sites ?

Internet permet entre autres de regarder des vidéos de chats et de gérer des portefeuilles de cryptomonnaies. mais vous ne voudriez pas que fluffycats.example ait accès à vos précieux cryptocoins ! Heureusement, les sites Web ne peuvent généralement pas accéder aux données des uns et des autres dans leur navigateur grâce à Règle. Toutefois, des sites Web malveillants peuvent essayer de contourner cette règle pour attaquer d'autres sites Web, et Parfois, des bugs de sécurité sont détectés dans le code du navigateur qui applique la règle d'origine identique. La L'équipe Chrome s'efforce de corriger ces bugs le plus rapidement possible.

L'isolation de sites est une fonctionnalité de sécurité de Chrome qui constitue une ligne de défense supplémentaire pour empêcher ces attaques ont moins de chances de réussir. Elle garantit que les pages de différents sites Web sont toujours dans des processus différents, chacun s'exécutant dans un bac à sable qui limite ce que le processus est autorisé à faire. Il empêche également le processus de recevoir certains types de données sensibles provenant d’autres sites. En tant que Avec l'isolation de sites, il est beaucoup plus difficile pour un site Web malveillant d'utiliser des techniques des attaques par canal auxiliaire comme Spectre pour voler des données à d’autres sites. Lorsque l'équipe Chrome termine mesures supplémentaires, l'isolation de sites est également utile même lorsque la page d'un pirate informatique peut endommager certaines des règles dans son propre processus.

Dans les faits, l'isolation de sites empêche les sites Web non fiables d'accéder à des informations ou de les voler. de vos comptes sur d'autres sites Web. Il offre une protection supplémentaire contre différents types les bugs de sécurité tels que des attaques de canaux secondaires par Meltdown et Spectre.

Pour en savoir plus sur l'isolation de sites, consultez notre article sur le blog Google sur la sécurité.

Blocage de lecture entre origines multiples

Même lorsque toutes les pages intersites font l'objet de processus distincts, les pages peuvent toujours demander légitimement certaines sous-ressources intersites, comme les images et JavaScript. Une page Web malveillante pourrait utiliser un <img> pour charger un fichier JSON contenant des données sensibles, comme votre solde bancaire:

<img src="https://your-bank.example/balance.json" />
<!-- Note: the attacker refused to add an `alt` attribute, for extra evil points. -->

Sans l'isolation de sites, le contenu du fichier JSON sera stocké dans la mémoire du moteur de rendu. À ce stade, le moteur de rendu remarque qu'il ne s'agit pas d'un format d'image valide et n'affiche pas une image. Mais l’attaquant pourrait alors exploiter une vulnérabilité comme Spectre pour potentiellement lire cette ou un fragment de mémoire.

Au lieu d'utiliser <img>, le pirate informatique pourrait également utiliser <script> pour valider les données sensibles sur mémoire:

<script src="https://your-bank.example/balance.json"></script>

Le blocage de lecture d'origines multiples, ou CORB, est une nouvelle fonctionnalité de sécurité qui empêche le contenu balance.json d'entrer dans la mémoire du processus du moteur de rendu en fonction de son type MIME.

Voyons comment fonctionne CORB. Un site Web peut demander deux types de ressources à un serveur:

  1. ressources de données telles que des documents HTML, XML ou JSON
  2. Ressources multimédias (images, JavaScript, CSS ou polices)

Un site Web peut recevoir des ressources de données de sa propre origine ou d'autres origines avec des en-têtes CORS permissifs tels que Access-Control-Allow-Origin: * Les ressources multimédias, quant à elles, peuvent être incluses depuis n'importe quelle source même sans en-têtes CORS permissifs.

CORB empêche le processus du moteur de rendu de recevoir une ressource de données multi-origines (HTML, XML ou JSON) si:

  • La ressource comporte un en-tête X-Content-Type-Options: nosniff.
  • CORS n'autorise pas explicitement l'accès à la ressource

Si l'en-tête X-Content-Type-Options: nosniff n'est pas défini pour la ressource de données multi-origines, CORB tente de renifler le corps de la réponse pour déterminer s'il est au format HTML, XML ou JSON. C'est nécessaire, car certains serveurs Web sont mal configurés et diffusent des images en tant que text/html, par exemple.

Les ressources de données bloquées par la règle CORB sont présentées au processus comme vides, bien que la requête a toujours lieu en arrière-plan. Ainsi, une page Web malveillante a du mal en intégrant des données intersites dans son processus de vol.

Pour une sécurité optimale et bénéficier de CORB, nous vous recommandons de prendre les mesures suivantes:

  • Marquez les réponses avec le bon en-tête Content-Type. Par exemple, les ressources HTML doivent être diffusées en tant que ressources JSON text/html avec un type MIME JSON et des ressources XML avec un type MIME XML).
  • Désactivez le reniflage à l'aide de l'en-tête X-Content-Type-Options: nosniff. Sans cet en-tête, Chrome analyse rapidement le contenu pour essayer de confirmer que le type est correct, mais comme cela laisse passer les réponses pour éviter de bloquer des éléments tels que les fichiers JavaScript, il vaut mieux faire le bien vous-même.

Pour en savoir plus, consultez les Article CORB pour les développeurs Web ou notre vidéo explicative CORB approfondie.

Pourquoi les développeurs Web devraient-ils se soucier de l'isolation de sites ?

Dans la plupart des cas, l'isolation de sites est une fonctionnalité de navigateur qui s'exécute en arrière-plan et qui n'est pas directement aux développeurs Web. Par exemple, il n'est pas nécessaire d'apprendre à utiliser une nouvelle API Web exposée. En général, les sites Web ne devraient pas faire la différence lorsqu'elles sont exécutées avec ou sans l'isolation de sites.

Il existe toutefois quelques exceptions à cette règle. L'activation de l'isolation de sites s'accompagne de quelques d'éventuels effets secondaires qui pourraient affecter votre site Web. Nous maintenons Une liste des problèmes connus liés à l'isolation de sites et nous détaillerons les plus importants ci-dessous.

La mise en page en pleine page n'est plus synchrone

Avec l'isolation de sites, la mise en page n'est plus garantie comme étant synchrone, car les cadres de une page peut maintenant être répartie sur plusieurs processus. Cela peut avoir un impact sur les pages si elles supposent qu'un le changement de mise en page se propage immédiatement à tous les cadres de la page.

Prenons l'exemple d'un site Web nommé fluffykittens.example qui communique avec un widget de réseau social hébergé sur social-widget.example:

<!-- https://fluffykittens.example/ -->
<iframe src="https://social-widget.example/" width="123"></iframe>
<script>
  const iframe = document.querySelector('iframe');
  iframe.width = 456;
  iframe.contentWindow.postMessage(
    // The message to send:
    'Meow!',
    // The target origin:
    'https://social-widget.example'
  );
</script>

Au début, la largeur de l'élément <iframe> du widget de réseau social est de 123 pixels. Mais ensuite, la page de FluffyKittens définit la largeur sur 456 pixels (mise en page avec déclenchement) et envoie un message au widget de réseau social. qui comporte le code suivant:

<!-- https://social-widget.example/ -->
<script>
  self.onmessage = () => {
    console.log(document.documentElement.clientWidth);
  };
</script>

Chaque fois que le widget de réseau social reçoit un message via l'API postMessage, il consigne la largeur de son élément <html> racine.

Quelle valeur de largeur est consignée ? Avant l'activation de l'isolation de sites dans Chrome, la réponse était 456. Accès document.documentElement.clientWidth force la mise en page, qui était synchrone avant Chrome. la fonctionnalité d'isolation de sites est activée. Toutefois, lorsque l'isolation de sites est activée, le widget de réseau social multi-origines la remise en page s'effectue désormais de manière asynchrone dans un processus distinct. De ce fait, la réponse peut désormais aussi être 123, c'est-à-dire l'ancienne valeur width.

Si une page modifie la taille d'un élément <iframe> multi-origines, puis lui envoie une valeur postMessage, avec Isolation de site : la trame de réception ne connaît peut-être pas encore sa nouvelle taille lors de la réception du message. Plus En général, les pages risquent d'endommager les pages si elles supposent qu'un changement de mise en page se propage immédiatement à tous cadres sur la page.

Dans cet exemple particulier, une solution plus robuste définirait width dans le frame parent, et détecter ce changement dans <iframe> en écoutant un événement resize.

Les gestionnaires de déchargement peuvent expirer plus souvent

Lors de la navigation ou de la fermeture d'un cadre, l'ancien document ainsi que tous les documents sous-cadres qui y sont intégrés exécutent tous leur gestionnaire unload. Si la nouvelle navigation se produit dans le même processus de moteur de rendu (par exemple, une navigation d'origine identique), les gestionnaires unload de l'ancien document et de ses sous-cadres peuvent s'exécuter pour un délai arbitraire avant d'autoriser le commit de la nouvelle navigation.

addEventListener('unload', () => {
  doSomethingThatMightTakeALongTime();
});

Dans ce cas, les gestionnaires unload de tous les frames sont très fiables.

Toutefois, même sans l'isolation de sites, certaines navigations entre les frames principaux sont inter-processus, ce qui a un impact le comportement du gestionnaire de déchargement. Par exemple, si vous passez de old.example à new.example en saisissant l'URL dans la barre d'adresse, la navigation new.example s'effectue dans un nouveau processus. Le déchargement Les gestionnaires de old.example et de ses sous-frames s'exécutent dans le processus old.example en arrière-plan. après l'affichage de la page new.example, et les anciens gestionnaires de déchargement sont arrêtés se terminer dans un certain délai. Étant donné que les gestionnaires de déchargement peuvent ne pas se terminer avant le délai d'inactivité, le comportement de déchargement est moins fiable.

Grâce à l'isolation de sites, toutes les navigations intersites deviennent inter-processus, de sorte que les documents provenant différents sites ne partagent pas de processus entre eux. Par conséquent, la situation ci-dessus s'applique et les gestionnaires de déchargement dans les <iframe> ont souvent des comportements d'arrière-plan et de délai avant expiration. décrites ci-dessus.

Autre différence due à l'isolation de sites : le nouvel ordre parallèle des gestionnaires de déchargement est le suivant : sans isolation de sites, les gestionnaires de déchargement s'exécutent dans un ordre descendant strict sur les frames. Mais avec Site Web, Isolation : les gestionnaires de déchargement s'exécutent en parallèle sur différents processus.

Voilà les conséquences fondamentales de l'activation de l'isolation de sites. L'équipe Chrome travaille sur améliorant la fiabilité des gestionnaires de déchargement pour les cas d'utilisation courants, dans la mesure du possible. Nous des bugs dans lesquels les gestionnaires de déchargement des sous-cadres ne sont pas encore en mesure d'utiliser certaines fonctionnalités pour les résoudre.

Il est important d'envoyer des pings de fin de session pour les gestionnaires de déchargement. Cela se fait généralement comme ce qui suit:

addEventListener('pagehide', () => {
  const image = new Image();
  img.src = '/end-of-session';
});

Une meilleure approche plus robuste à la lumière de ce changement consiste à utiliser navigator.sendBeacon à la place:

addEventListener('pagehide', () => {
  navigator.sendBeacon('/end-of-session');
});

Si vous avez besoin de plus de contrôle sur la requête, vous pouvez utiliser l'option keepalive de l'API Fetch:

addEventListener('pagehide', () => {
  fetch('/end-of-session', {keepalive: true});
});

Conclusion

Avec l'isolation de sites, il est plus difficile pour les sites Web non fiables d'accéder à des informations sur votre comptes sur d'autres sites Web en isolant chaque site dans son propre processus. CORB essaie pour maintenir les ressources de données sensibles hors du processus du moteur de rendu. Les recommandations ci-dessus vous permettent pour tirer le meilleur parti de ces nouvelles fonctionnalités de sécurité.

Grâce à Alex Moshchuk, Charlie Reis, Jason Miller, Nasko Oskov, Philip Walton, Shubhie Panicker et Thomas Steiner d'avoir lu une version brouillon de cet article et de donner leur avis.