Changements prévus à propos de la mémoire partagée

Un travail de standardisation est en cours afin de permettre à nouveau l'utilisation des objets SharedArrayBuffer, mais des modifications sont nécessaires afin que ceux-ci puissent être utilisés entre des threads (par défaut postMessage() lève une exception pour les objets SharedArrayBuffer). Ces modifications améliorent l'isolation entre les sites et aident à réduire l'impact des attaques utilisant des minuteurs à haute résolution, comme ceux pouvant être créés avec de la mémoire partagée.

Note : À partir de Firefox 79, les fonctionnalités décrites dans ce document sont activées par défaut.

En-têtes HTTP

Pour commencer, les documents doivent utiliser un contexte sécurisé.

Pour les documents de plus haut niveau, deux en-têtes doivent être présents :

Avec ces deux en-têtes ainsi paramétrés, postMessage() ne déclenchera plus d'exceptions pour les objets SharedArrayBuffer et la mémoire partagée entre les threads sera donc disponible.

Les documents imbriqués et les workers dédiés devront également utiliser l'en-tête Cross-Origin-Embedder-Policy (en-US) avec la même valeur. Aucun changement supplémentaire n'est nécessaire pour les documents imbriqués de la même origine et pour les sous-ressources. Les documents imbriqués et les sous-ressources d'un même site mais d'une origine différente devront fixer l'en-tête Cross-Origin-Resource-Policy (en-US) avec la valeur same-site. Dans le cas d'une origine et d'un site différent, ce même en-tête devra avoir la valeur cross-origin. On notera qu'utiliser toute autre valeur que same-origin pour Cross-Origin-Resource-Policy (en-US) ouvre la porte à des attaques potentielles, telles que Spectre.

On notera que l'en-tête Cross-Origin-Opener-Policy (en-US) limite la capacité à retenir une référence vers une popup. L'accès direct entre deux fenêtres de plus haut niveau fonctionnera uniquement si elles partagent la même origine et que les deux en-têtes ont les mêmes valeurs.

Modifications de l'API JavaScript

En raison de ces nouvelles contraintes, quelques modifications sont apportées à l'API :

  • L'objet Atomics est toujours disponible.
  • En principe, les objets SharedArrayBuffer sont toujours disponibles. En pratique, il est nécessaire que les deux en-têtes mentionnés soient définis, sinon le constructeur rattaché à l'objet global est masqué. On peut espérer que cette restriction soit levée à l'avenir. WebAssembly.Memory peut toujours être utilisé afin d'obtenir une instance.
  • À moins que les deux en-têtes mentionnés avant soient définis, les différentes API postMessage() lèveront une exception pour les objets SharedArrayBuffer. Si les en-têtes sont bien paramétrés, postMessage() fonctionnera sur les objets Window et les workers dédiés et permettra le partage de la mémoire.
  • Afin d'éviter d'avoir à vérifier si postMessage() provoque des erreurs, self.crossOriginIsolated est en cours de standardisation : il s'agit d'un accesseur renvoyant un booléen indiquant si les en-têtes sont bien définis et qui est disponible dans les contextes de la fenêtre et des workers.

Mémoire partagée en WebAssembly

La proposition sur les threads WebAssembly permet à des objets WebAssembly.Memory d'être créés avec un nouveau marqueur shared pour le constructeur. Lorsque ce marqueur vaut true, l'objet Memory construit peut être partagé entre les workers avec postMessage(), comme SharedArrayBuffer, et le buffer de l'objet Memory correspondant est un objet SharedArrayBuffer. Aussi, les conditions exposées ci-avant pour le partage d'un SharedArrayBuffer entre les workers s'appliquent également au partage d'un objet WebAssembly.Memory.

Cette proposition définit également un nouvel ensemble d'instructions atomiques. À l'instar de SharedArrayBuffer et de ses méthodes qui sont autorisées sans condition (seul le partage entre threads est conditionné aux en-têtes), les instructions atomiques WebAssembly sont aussi autorisées sans condition.

Voir aussi