Mises à jour de SharedArrayBuffer dans Android 88 et de Chrome 92 pour ordinateur

On peut dire que SharedArrayBuffer a connu un lancement un peu difficile sur le Web, mais les choses se calment. Voici quelques points à retenir :

En bref

  • SharedArrayBuffer est actuellement compatible avec Firefox 79 et versions ultérieures, et sera disponible dans Android Chrome 88. Toutefois, il n'est disponible que pour les pages isolées multi-origines.
  • SharedArrayBuffer est actuellement disponible dans la version pour ordinateur de Chrome, mais à partir de Chrome 92, il sera limité aux pages isolées multi-origine. Si vous pensez ne pas pouvoir effectuer ce changement à temps, vous pouvez vous inscrire à un test d'origine pour conserver le comportement actuel jusqu'à Chrome 113 au moins.
  • Si vous prévoyez d'activer l'isolation multi-origine pour continuer à utiliser SharedArrayBuffer, évaluez l'impact que cela aura sur les autres éléments multi-origine de votre site Web, tels que les emplacements publicitaires. Vérifiez si SharedArrayBuffer est utilisé par l'une de vos ressources tierces pour comprendre l'impact et obtenir des conseils.

Présentation de l'isolation multi-origine

Vous pouvez isoler une page multi-origine en la diffusant avec les en-têtes suivants :

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

Une fois cette opération effectuée, votre page ne pourra pas charger de contenu multi-origine, sauf si la ressource l'autorise explicitement via un en-tête Cross-Origin-Resource-Policy ou des en-têtes CORS (Access-Control-Allow-*, etc.).

Il existe également une API Reporting qui vous permet de collecter des données sur les requêtes ayant échoué en raison de Cross-Origin-Embedder-Policy et Cross-Origin-Opener-Policy.

Si vous pensez ne pas pouvoir effectuer ces modifications à temps pour Chrome 92, vous pouvez vous inscrire à un test d'origine pour conserver le comportement actuel de Chrome sur ordinateur jusqu'à Chrome 113 au moins.

Pour obtenir plus de conseils et d'informations sur l'isolation cross-origin, consultez la section Pour en savoir plus au bas de cette page.

Comment y sommes-nous parvenus ?

SharedArrayBuffer est arrivé dans Chrome 60 (en juillet 2017, pour ceux qui pensent en termes de dates plutôt que de versions de Chrome), et tout allait bien. Pendant six mois.

En janvier 2018, une faille de sécurité a été découverte dans certains processeurs populaires. Pour en savoir plus, consultez l'annonce. En résumé, cela signifie que le code peut utiliser des minuteurs haute résolution pour lire la mémoire à laquelle il ne devrait pas avoir accès.

C'était un problème pour nous, les fournisseurs de navigateurs, car nous voulons autoriser les sites à exécuter du code sous la forme de JavaScript et de WASM, mais contrôler strictement la mémoire à laquelle ce code peut accéder. Si j'arrive sur mon site Web, je ne devrais pas pouvoir lire quoi que ce soit sur le site de banque en ligne que vous avez également ouvert. En fait, je ne devrais même pas savoir que vous avez ouvert le site de votre banque en ligne. Il s'agit des principes de base de la sécurité Web.

Pour y remédier, nous avons réduit la résolution de nos minuteurs haute résolution tels que performance.now(). Toutefois, vous pouvez créer un minuteur haute résolution à l'aide de SharedArrayBuffer en modifiant la mémoire dans une boucle serrée dans un nœud de calcul et en la relisant dans un autre thread. Il n'a pas été possible d'atténuer efficacement ce problème sans impacter fortement le code bien intentionné. SharedArrayBuffer a donc été désactivé.

Une mesure d'atténuation générale consiste à s'assurer que le processus système d'une page Web ne contient pas de données sensibles provenant d'ailleurs. Chrome avait investi dans une architecture multiprocessus dès le début (vous vous souvenez de la bande dessinée ?), mais il existait encore des cas où les données de plusieurs sites pouvaient se retrouver dans le même processus :

<iframe src="https://your-bank.example/balance.json"></iframe>
<script src="https://your-bank.example/balance.json"></script>
<link rel="stylesheet" href="https://your-bank.example/balance.json" />
<img src="https://your-bank.example/balance.json" />
<video src="https://your-bank.example/balance.json"></video>
<!-- …and more… -->

Ces API ont un comportement "hérité" qui permet d'utiliser du contenu provenant d'autres origines sans que celles-ci aient besoin de l'activer. Ces requêtes sont effectuées avec les cookies de l'autre origine. Il s'agit donc de requêtes "connectées" complètes. Aujourd'hui, les nouvelles API exigent que l'autre origine s'inscrive à l'aide de CORS.

Nous avons contourné ces anciennes API en empêchant le contenu d'entrer dans le processus de la page Web s'il semblait "incorrect", et nous l'avons appelé blocage de la lecture cross-origin. Dans les cas ci-dessus, nous n'autoriserions pas l'entrée de JSON dans le processus, car il ne s'agit pas d'un format valide pour ces API. Autrement dit, à l'exception des iFrames. Pour les iFrames, nous plaçons le contenu dans un processus différent.

Ces mesures d'atténuation étant en place, nous avons réintroduit SharedArrayBuffer dans Chrome 68 (juillet 2018), mais uniquement sur ordinateur. Les exigences supplémentaires en termes de processus nous ont empêchés de faire de même sur les appareils mobiles. Il a également été noté que la solution de Chrome était incomplète, car nous ne bloquions que les formats de données "incorrects", alors qu'il est possible (bien que rare) que des images, des fichiers CSS ou JS valides à des URL devinables contiennent des données privées.

Les spécialistes des normes Web se sont réunis pour trouver une solution multi-navigateur plus complète. La solution consistait à permettre aux pages de déclarer "Je renonce par la présente à ma capacité à intégrer du contenu d'une autre origine dans ce processus sans leur consentement". Cette déclaration s'effectue via les en-têtes COOP et COEP diffusés avec la page. Le navigateur applique cette règle, et en échange, la page obtient l'accès à SharedArrayBuffer et à d'autres API aux fonctionnalités similaires. D'autres origines peuvent activer l'intégration de contenu via Cross-Origin-Resource-Policy ou CORS.

Firefox a été le premier à implémenter SharedArrayBuffer avec cette restriction, dans la version 79 (juillet 2020).

Ensuite, en janvier 2021, j'ai écrit cet article et vous l'avez lu. Bonjour.

Et c'est là où nous en sommes maintenant. Chrome 88 réintroduit SharedArrayBuffer sur Android pour les pages isolées multi-origines, et Chrome 92 applique les mêmes exigences aux ordinateurs de bureau, à la fois pour assurer la cohérence et pour obtenir une isolation multi-origine totale.

Retarder la modification de Chrome pour ordinateur

Il s'agit d'une exception temporaire sous la forme d'un "test d'origine" qui donne aux utilisateurs plus de temps pour implémenter des pages isolées multi-origines. Il permet d'activer SharedArrayBuffer sans que la page soit isolée multi-origine. L'exception expire dans Chrome 113 et ne s'applique qu'à la version de Chrome pour ordinateur.

  1. Demandez un jeton pour votre origine.
  2. Ajoutez le jeton à vos pages. Pour ce faire, vous disposez de deux méthodes :
    • Ajoutez une balise origin-trial <meta> à l'en-tête de chaque page. Par exemple, cela peut ressembler à ceci :
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • Si vous pouvez configurer votre serveur, vous pouvez également ajouter le jeton à l'aide d'un en-tête HTTP Origin-Trial. L'en-tête de réponse obtenu devrait ressembler à ceci :
      Origin-Trial: TOKEN_GOES_HERE

Documentation complémentaire

Photo de bannière par Daniel Gregoire sur Unsplash