Chrome 67 pour ordinateur de bureau propose une nouvelle fonctionnalité appelée isolation de sites, activée par défaut. Cet article explique en quoi consiste l'isolation de site, pourquoi elle est nécessaire et pourquoi les développeurs Web doivent en tenir compte.
Qu'est-ce que l'isolation de sites ?
Internet est fait pour regarder des vidéos de chats et gérer des portefeuilles de cryptomonnaies, entre autres. Mais vous ne voulez pas que fluffycats.example
ait accès à vos précieuses cryptomonnaies. Heureusement, les sites Web ne peuvent généralement pas accéder aux données des autres dans le navigateur grâce à la règle de même origine. Toutefois, des sites Web malveillants peuvent tenter de contourner cette règle pour attaquer d'autres sites Web. De plus, des bugs de sécurité sont parfois détectés dans le code du navigateur qui applique la règle d'origine commune. L'équipe Chrome s'efforce de corriger ces bugs le plus rapidement possible.
L'isolation de site est une fonctionnalité de sécurité de Chrome qui offre une ligne de défense supplémentaire pour réduire la probabilité de réussite de ces attaques. Elle garantit que les pages de différents sites Web sont toujours placées dans des processus différents, chacun exécuté dans un bac à sable qui limite les actions autorisées du processus. Elle empêche également le processus de recevoir certains types de données sensibles provenant d'autres sites. Par conséquent, avec l'isolation de site, il est beaucoup plus difficile pour un site Web malveillant d'utiliser des attaques par canal auxiliaire spéculatives telles que Spectre pour voler des données à d'autres sites. À mesure que l'équipe Chrome finalise les mesures d'application supplémentaires, l'isolation de site est également utile, même si la page d'un pirate informatique peut enfreindre certaines des règles dans son propre processus.
L'isolation de site complique efficacement la tâche des sites Web non approuvés qui tentent d'accéder à des informations de comptes sur d'autres sites Web ou de les voler. Il offre une protection supplémentaire contre divers types de bugs de sécurité, tels que les attaques par canal auxiliaire Meltdown et Spectre récentes.
Pour en savoir plus sur l'isolation de site, consultez cet article sur le blog Google Security.
Cross-Origin Read Blocking
Même lorsque toutes les pages intersites sont placées dans des processus distincts, elles peuvent toujours légitimement demander certaines sous-ressources intersites, telles que des images et du code JavaScript. Une page Web malveillante peut utiliser un élément <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 site, le contenu du fichier JSON arriverait dans la mémoire du processus de rendu, à quel point le moteur de rendu remarque qu'il ne s'agit pas d'un format d'image valide et ne n'affiche pas d'image. Toutefois, le pirate informatique peut ensuite exploiter une faille comme Spectre pour lire potentiellement ce bloc de mémoire.
Au lieu d'utiliser <img>
, le pirate informatique peut également utiliser <script>
pour enregistrer les données sensibles dans la mémoire:
<script src="https://your-bank.example/balance.json"></script>
Le blocage de la lecture inter-origine (CORB, Cross-Origin Read Blocking) est une nouvelle fonctionnalité de sécurité qui empêche le contenu de balance.json
d'entrer dans la mémoire du processus de rendu en fonction de son type MIME.
Voyons comment fonctionne le CORB. Un site Web peut demander deux types de ressources à un serveur:
- ressources de données telles que des documents HTML, XML ou JSON
- ressources multimédias telles que des images, du code JavaScript, du code CSS ou des polices
Un site Web peut recevoir des ressources de données à partir de sa propre origine ou d'autres origines avec des en-têtes CORS permissifs tels que Access-Control-Allow-Origin: *
. En revanche, les ressources multimédias peuvent être incluses depuis n'importe quelle origine, même sans en-têtes CORS permissifs.
CORB empêche le processus de rendu de recevoir une ressource de données inter-origines (HTML, XML ou JSON) si:
- la ressource comporte un en-tête
X-Content-Type-Options: nosniff
; - Le 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 inter-origines, CORB tente d'analyser le corps de la réponse pour déterminer s'il s'agit de HTML, de XML ou de JSON. Cela 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 stratégie CORB sont présentées au processus comme vides, bien que la requête se produise toujours en arrière-plan. Par conséquent, une page Web malveillante a du mal à extraire des données intersites dans son processus pour les voler.
Pour une sécurité optimale et pour profiter de CORB, nous vous recommandons de suivre les conseils ci-dessous:
- Marquez les réponses avec l'en-tête
Content-Type
approprié. (par exemple, les ressources HTML doivent être servies en tant quetext/html
, les ressources JSON avec un type MIME JSON et les ressources XML avec un type MIME XML). - Désactivez l'énumération à l'aide de l'en-tête
X-Content-Type-Options: nosniff
. Sans cet en-tête, Chrome effectue une analyse rapide du contenu pour essayer de confirmer que le type est correct. Toutefois, comme il est plus susceptible d'autoriser les réponses pour éviter de bloquer des éléments tels que les fichiers JavaScript, il est préférable de le faire vous-même.
Pour en savoir plus, consultez l'article sur le CORB pour les développeurs Web ou notre explication détaillée du CORB.
Pourquoi les développeurs Web doivent-ils se soucier de l'isolation de site ?
Dans la plupart des cas, l'isolation de site est une fonctionnalité de navigateur en coulisse qui n'est pas directement exposée aux développeurs Web. Par exemple, il n'y a pas de nouvelle API exposée sur le Web à apprendre. En général, les pages Web ne devraient pas pouvoir faire la différence lorsqu'elles s'exécutent avec ou sans l'isolation de site.
Toutefois, il existe quelques exceptions à cette règle. L'activation de l'isolation de site comporte quelques effets secondaires subtils qui peuvent affecter votre site Web. Nous maintenons une liste des problèmes connus liés à l'isolation de site, et nous développons les plus importants ci-dessous.
La mise en page en pleine page n'est plus synchrone
Avec l'isolation de site, la mise en page de la page entière n'est plus garantie comme étant synchrone, car les cadres d'une page peuvent désormais être répartis sur plusieurs processus. Cela peut affecter les pages si elles supposent qu'un 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 <iframe>
du widget de réseau social est de 123
pixels. Toutefois, la page FluffyKittens modifie la largeur sur 456
pixels (déclenchement de la mise en page) et envoie un message au widget de réseau social, dont le code est le 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 racine <html>
.
Quelle valeur de largeur est enregistrée ? Avant que Chrome n'active l'isolation de sites, la réponse était 456
. L'accès à document.documentElement.clientWidth
force la mise en page, qui était synchrone avant que Chrome n'active l'isolation de sites. Toutefois, lorsque l'isolation de sites est activée, la redisposition du widget social multi-origine se produit désormais de manière asynchrone dans un processus distinct. Par conséquent, la réponse peut désormais également être 123
, c'est-à-dire l'ancienne valeur width
.
Si une page modifie la taille d'un <iframe>
inter-origine, puis lui envoie un postMessage
, avec l'isolation de site, le frame destinataire ne connaît peut-être pas encore sa nouvelle taille lorsqu'il reçoit le message. Plus généralement, cela peut entraîner des erreurs sur les pages si elles supposent qu'un changement de mise en page se propage immédiatement à tous les cadres de la page.
Dans cet exemple particulier, une solution plus robuste consisterait à définir la width
dans le frame parent et à détecter ce changement dans la <iframe>
en écoutant un événement resize
.
Les gestionnaires de déchargement peuvent expirer plus souvent
Lorsqu'un frame navigue ou se ferme, l'ancien document ainsi que tous les documents de sous-cadre qui y sont intégrés exécutent leur gestionnaire unload
. Si la nouvelle navigation se produit dans le même processus de rendu (par exemple, pour une navigation de même origine), les gestionnaires unload
de l'ancien document et de ses sous-cadres peuvent s'exécuter pendant une durée arbitrairement longue avant d'autoriser la nouvelle navigation à s'engager.
addEventListener('unload', () => {
doSomethingThatMightTakeALongTime();
});
Dans ce cas, les gestionnaires unload
de tous les cadres sont très fiables.
Toutefois, même sans l'isolation de site, certaines navigations dans le frame principal sont inter-processus, ce qui a un impact sur 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
se produit dans un nouveau processus. Les gestionnaires de déchargement pour old.example
et ses sous-cadres s'exécutent dans le processus old.example
en arrière-plan, après l'affichage de la page new.example
. Les anciens gestionnaires de déchargement sont arrêtés s'ils ne se terminent pas dans un délai donné. Étant donné que les gestionnaires de déchargement peuvent ne pas se terminer avant le délai avant expiration, le comportement de déchargement est moins fiable.
Avec l'isolation de sites, toutes les navigations intersites deviennent interprocessus, de sorte que les documents de différents sites ne partagent pas de processus entre eux. Par conséquent, la situation ci-dessus s'applique dans un plus grand nombre de cas, et les gestionnaires de déchargement dans les <iframe>
ont souvent les comportements en arrière-plan et les délais avant expiration décrits ci-dessus.
Une autre différence résultant de l'isolation de site est le nouvel ordre parallèle des gestionnaires de déchargement : sans isolation de site, les gestionnaires de déchargement s'exécutent dans un ordre strict de haut en bas sur les cadres. Toutefois, avec l'isolation de sites, les gestionnaires de déchargement s'exécutent en parallèle dans différents processus.
Il s'agit de conséquences fondamentales de l'activation de l'isolation de site. L'équipe Chrome s'efforce d'améliorer la fiabilité des gestionnaires de déchargement pour les cas d'utilisation courants, dans la mesure du possible. Nous sommes également au courant de bugs où les gestionnaires de déchargement de sous-cadres ne peuvent pas encore utiliser certaines fonctionnalités, et nous nous efforçons de les résoudre.
Les gestionnaires de déchargement sont importants pour envoyer des pings de fin de session. Pour ce faire, procédez comme suit:
addEventListener('pagehide', () => {
const image = new Image();
img.src = '/end-of-session';
});
Une approche plus robuste compte tenu 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
L'isolation de sites complique la tâche des sites Web non approuvés qui tentent d'accéder à des informations de comptes sur d'autres sites ou de les voler. Pour ce faire, elle isole chaque site dans son propre processus. Dans ce cadre, CORB tente de maintenir les ressources de données sensibles en dehors du processus de rendu. Nos recommandations ci-dessus vous permettront de profiter pleinement de ces nouvelles fonctionnalités de sécurité.
Merci à Alex Moshchuk, Charlie Reis, Jason Miller, Nasko Oskov, Philip Walton, Shubhi Panicker et Thomas Steiner d'avoir lu une version préliminaire de cet article et de nous avoir fait part de leurs commentaires.