La Sandbox Firefox sous Linux

MISC n° 078 | mars 2015 | Guillaume Destuynder
Creative Commons
  • Actuellement 0 sur 5 étoiles
0
Merci d'avoir participé !
Vous avez déjà noté cette page, vous ne pouvez la noter qu'une fois !
Votre note a été changée, merci de votre participation !
Firefox est encore à ses débuts – lorsqu’il s’agit de se protéger contre l’exploitation des failles du navigateur. En effet, lorsqu’une faille a été découverte (exécution de code arbitraire, dépassement de tampon, etc.) il est possible de limiter, voire complètement empêcher l'exécution de processus ou l'accès aux données ou ressources. Cela rend la tâche nettement plus ardue pour l’attaquant.

Ce type de protection est supporté par la couche noyau du système – dans notre cas, Linux.

Les mécanismes proposés par le noyau permettent d’isoler les processus et de restreindre l’accès aux ressources (fichiers, mémoire, périphériques…). L’application desdits mécanismes et la séparation des tâches par processus est-ce que l’on appelle une « sandbox » ou bac à sable en français – c’est-à-dire une aire de « jeu » sans danger et de laquelle on ne peut pas sortir sans autorisation préalable.

Cette protection a récemment été ajoutée dans Firefox Nightly (la version de développement de Firefox qui est compilée toutes les « nuits ») et Firefox OS, le système de Mozilla pour téléphones portables.

1. Comment ça marche, une Sandbox ?

Pour comprendre le fonctionnement d’une sandbox, il faut tout d’abord comprendre certains aspects du fonctionnement des processeurs (CPU) et du noyau du système.

1.1 La séparation des processus

Les premiers processeurs étaient prévus pour faire tourner un seul programme. Du coup, le programme en question avait un accès complet à toutes les ressources, et toute la mémoire vive (RAM) connectée.

Cependant, les processeurs sont très vite montés en puissance et en rapidité d’exécution – suffisamment rapide pour exécuter plusieurs segments de programmes différents et suffisamment vite pour donner l’impression que tous les programmes tournent en même temps (aussi appelé système multitâche).

Dans ce cas, tous les programmes du système partagent le même espace mémoire et par conséquent, un programme peut modifier la mémoire et le fonctionnement d’un autre programme, ou même pire, du noyau du système…

En fait, ces systèmes sont bien connus par certain d’entre nous : Windows 95, 98, ME, Mac OS 9, etc.

Et pour cause ! Un bug d’adressage mémoire dans un programme ? Le système se fige et il faut redémarrer l’ordinateur.

Ces systèmes utilisent le mode d’adressage mémoire du processeur dit « mémoire réelle », qui effectivement présente toute la mémoire réelle de la machine directement à tous les processus.

Sur la plate-forme Intel x86 par exemple, il est possible d’activer un autre mode d’adressage : le mode « mémoire protégée ». Il est disponible depuis 1982 et le processeur 80286 (mieux connu en tant que processeur « 286 ») et a été rapidement amélioré sur le processeur suivant, le 80386 (« 386 »). La partie du CPU en charge de la gestion mémoire s’appelle le MMU (« Memory Management Unit »).

La mémoire protégée permet au MMU d’allouer un espace mémoire virtuel pour chaque programme. Chaque programme pense ainsi avoir accès à toute la mémoire du système.

En réalité, le MMU se débrouille pour allouer uniquement l’espace véritablement utilisé par le programme. Il est même possible d’allouer de la mémoire sur le disque dur (souvent appelée « swap ») et qui, bien que plus lente, permet d’utiliser plus de mémoire que disponible en RAM seule.

Comme son nom l’indique, la mémoire protégée ne permet pas l’accès à la mémoire des autres programmes. Un programme ne voit que son propre espace mémoire. Il existe cependant plusieurs mécanismes pour communiquer entre programmes comme la mémoire partagée (dont l’accès est aussi contrôlé en lecture et écriture selon une table définie par un appel au noyau – 2 programmes ont besoin d’un droit d’accès à la même zone mémoire partagée).

Un autre mécanisme courant est les sockets de communication, type Unix, TCP, etc., et parfois même de simples fichiers (un processus écrit dans le fichier, l’autre le lit).

Le noyau du système fonctionne donc dans un mode spécifique du CPU lui permettant d’arbitrer ces droits d’accès et autres fonctions spéciales. C’est la tâche du système ayant le plus haut niveau de privilèges – plus haut que les utilisateurs dits administrateurs du système. Ces derniers ne font que demander au noyau d’accéder aux ressources (via l’intermédiaire d’appels système au noyau, appelés « system calls » ou « syscalls ») et de changer certains réglages, c’est le noyau qui effectue le changement et décide s’il est autorisé ou non.

1.2 La restriction d’accès aux ressources par processus

Nous avons donc établi que les données de chaque processus sont séparées en mémoire par le MMU, et que certaines fonctions du noyau permettent aux programmes de communiquer ou effectuer d’autres tâches privilégiées.

C’est donc naturellement dans le noyau que se trouvent les mécanismes de gestion d’accès aux ressources (fichiers, réseau, hardware…).

Traditionnellement, le noyau ne permet pas aux programmes démarrés par différents utilisateurs de partager leur mémoire, d’envoyer des signaux spéciaux (par exemple, le signal permettant de quitter ou tuer un autre processus), d’accéder aux fichiers stockés sur le disque dur, etc.

Ces accès ce font donc tous via les appels système.

Par exemple, lorsqu’un programme lit un fichier, il demande au noyau de l’ouvrir (appel système : open), puis de lire le contenu (« read ») ou écrire (« write »), puis finalement il ferme le fichier (« close »). Il existe plus de 300 appels système et de nouveaux appels sont ajoutés de temps en temps par les développeurs du noyau Linux.

De fait, le noyau gère les accès entre les processus et le MMU s’occupe de définir les bornes de séparation des données au niveau du processus.

1.3 Mécanismes de gestion d’accès du noyau Linux

1.3.1 Linux Capabilities (Capacités)

L’utilisateur administrateur dit « root » est un utilisateur comme un autre du point de vue du noyau, mais qui possède des capacités (« capabilities » ou « caps »). Celles-ci sont définies par défaut dans le noyau Linux :

Par exemple, CAP_DAC_OVERRIDE permet au root de lire, écrire et changer les attributs de tout fichier sur les disques locaux (cela représente donc la capacité de passer outre les restrictions du système de sécurité « DAC », ou « discretionary access control »).

DAC est le système de gestion d’accès par défaut du noyau Linux.

Il existe bien sûr d’autres capacités, et les utilisateurs non-root et certains processus peuvent y avoir accès si un utilisateur root le décide.

Cependant, le système de capacités n’est pas très flexible et son utilisation est donc limitée.

1.3.2 SELinux, AppArmor, etc.

D’autres modèles de sécurité plus avancés existent sous Linux. Beaucoup ont au moins entendu parler de SELinux (Security Enhanced Linux) par exemple.

En surface, SELinux est représenté par une liste de règles très précises de ce que les programmes et utilisateurs peuvent faire, ce qu’ils peuvent accéder, et permet de grouper ceux-ci par domaines et types.

Sous le capot, SELinux tourne au niveau du noyau et vérifie chaque appel système. Si ses règles ne permettent pas au processus de faire un certain appel système (et/ou certains arguments envoyés via cet appel système), il refuse l’appel.

Il y a un problème complexe avec SELinux : lors de l'écriture des règles, il est souvent difficile de prévoir ce que le processus va accéder et donc de décider a priori ce qui est autorisé ou non.

Cela dépend beaucoup de l’utilisation du système et de la façon dont le développeur a programmé son application.

1.3.3 Seccomp (Secure Computing Mode)

1.3.3.1 Mode 1

Seccomp est une option du noyau Linux qui permet de restreindre le nombre d’appels système utilisables par un processus, et/ou les arguments qui sont envoyés via ces appels système.

L’avantage de seccomp, c’est que contrairement à SELinux, le programme lui-même peut l’appeler et le configurer – une façon de dire « OK, noyau : démarre ma sandbox et restreint mes droits d’accès aux ressources maintenant ! ».

De cette façon, le développeur de l’application peut préciser lui-même les paramètres nécessaires pour que son programme fonctionne correctement – et non pas l’utilisateur.

Seccomp a tout d’abord été ajouté en tant que « seccomp mode 1» : ce mode ne permet que les appels système « read », « write », « exit » et « sigreturn » qui permettent au processus de lire/écrire sur les fichiers déjà ouverts, et de se terminer correctement.

Seccomp peut être activé à tout moment lors de l'exécution du programme, ce qui laisse le développeur accéder à toutes les ressources nécessaires (ouverture de fichiers, sockets, etc.), puis interdire l’ouverture de nouvelles ressources lorsque seccomp est activé.

Une fois actif, il est impossible de faire marche arrière jusqu’à ce que le programme se termine ou que le processus soit tué.

1.3.3.2 Mode 2

Le premier mode seccomp est un mode extrêmement restreint, et malgré le fait que cela rend la sandbox très difficile à contourner pour les attaquants, très peu de développeurs l’ont utilisé.

Le mode 2 permet de spécifier une liste d’appels système autorisé, et ses arguments : par exemple, autoriser l’appel « open », mais uniquement en mode « ajout de données » (O_APPEND), ou uniquement sur certains fichiers.

Un petit programme interne qui utilise le format de filtre réseau (« BPF filters ») du noyau permet de configurer ces appels.

Une fois le filtre actif, le noyau appellera le programme pour chaque appel système de ce processus.

De plus, puisqu’il est à présent possible de créer de nouveaux processus depuis la sandbox (via appel « execve » par exemple), les processus (et threads) enfants d’un processus ayant activé seccomp obtiendront le même filtre et seccomp sera automatiquement activé.

Il nous reste aussi l’appel « prctl » (signifie « process control ») qui est utilisé pour démarrer seccomp. Il est possible de remplacer le filtre seccomp par un filtre qui réautorise les appels système, et donc qui rend seccomp mode 2 inutile. Pour contourner ce grave problème, une autre nouvelle fonction du noyau est apparue : « No New Privileges » (NNP) ou « pas de nouveaux privilèges ». Elle est appelée juste avant d’activer seccomp et rend la possibilité d’ajouter des appels à autoriser sur le filtre seccomp impossible (ajouter une liste d’appels système à interdire est toutefois possible).

1.3.3.3 Utilisation de Seccomp

En général, un processus privilégié (dans ce cas, cela veut dire sans seccomp actif, mais non pas nécessairement avec plus de privilèges qu’un utilisateur régulier) communique avec le processus qui lui est sandboxé avec seccomp.

Cela permet de créer une interface et sa propre liste de règles qui sont valides par le processus privilégié et non plus uniquement par le noyau.

Seccomp et NNP sont activés via l’appel système « prctl » :

prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)

prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, filter_prog);

Sur Linux, chaque thread d’un même processus doit démarrer seccomp et NNP – il est plus facile de faire ceci depuis le thread principal avant de démarrer les threads enfants. Firefox utilise une fonction qui scanne tous les threads et démarre seccomp pour chacun d’entre eux.

1.3.4 Namespaces (Espaces de noms)

Une dernière méthode est devenue de plus en plus utilisée sous Linux – démocratisée par les programmes « LXC » et « Docker ».

Le principe de fonctionnement des namespaces est simple : chaque namespace est séparé et permet de lancer des processus, monter des partitions disque, créer des interfaces réseau, avoir une liste d’utilisateurs et une table de processus.

En pratique, cela ressemble à des machines virtuelles, en réalité, les namespaces sont des processus du même noyau.

Tout comme seccomp, les namespaces sont actives par le programme lui-même. De plus, le programme peut choisir quelles ressources il désire séparer. Il est possible de séparer uniquement les points de montage des partitions, ou uniquement la table des processus par exemple.

En d’autres mots : alors que seccomp pourrait interdire de lister les processus (en retournant une erreur de permission), un namespace ne retournera pas d’erreur, mais seuls les processus du même namespace seront listés.

2. Le défi pour Firefox : convertir un programme multi-thread en programme multiprocessus

Firefox est, depuis sa conception, un programme orienté multi-thread, c’est-à-dire qu’il permet de lancer plusieurs tâches simultanément dans le même processus, qui partagent le même espace mémoire et donc sans protection par le MMU.

Pour le sandboxing, c’est cette protection mémoire et la séparation stricte entre différents éléments du navigateur que nous recherchons.

Il faut donc effectuer certains choix pour la séparation des éléments : le contenu web n’a pas besoin de pouvoir lancer une calculette ou un interpréteur de ligne de commandes par exemple. Le système de rendu graphique non plus.

D’autres choix sont moins faciles, mais toujours intéressants du point de vue de la sécurité du navigateur : les plug-ins n’ont pas forcément besoin d’accéder aux cookies du navigateur, aux mots de passe sauvegardés, etc.

2.1 Un peu d’histoire de Firefox : les plug-ins « hors processus »

En fait, utiliser des processus différents pour certains éléments du navigateur est également intéressant pour d’autres raisons que la séparation des droits d’accès.

En particulier, le code externe – fourni via des librairies précompilées et souvent propriétaires (sans code source disponible aux équipes de programmeurs Firefox) – peut contenir des bugs et ceux-ci ayant accès à tout l’espace mémoire du processus de Firefox, peuvent facilement faire planter ou figer le navigateur. Étant développés séparément, ils ne sont pas toujours de bonne qualité, et ne bénéficient pas de la même batterie de tests que le code de Firefox, ou ne sont pas mis à jour en même temps que Firefox.

Par conséquent, les premiers pas du mode multiprocessus de Firefox (disponible depuis Firefox 3.6.4 sur Linux et Windows, Firefox 4 sur Mac OS X) se trouvent dans la gestion de plug-ins dits hors processus, c’est-à-dire en lançant les plug-ins dans un processus séparé qui communique avec le processus central de Firefox. Si le processus plug-in plante, Firefox n’est pas directement impacté.

L’écriture du code multiprocessus se devait d’être compatible avec les plug-ins actuels, qui utilisent l’interface de programmation dite NPAPI (« Netscape Plugin Application Programming Interface ») et qui dépendent beaucoup du code qui tourne dans Firefox.

Du coup, les processus plug-in font tourner une version très allégée du moteur Firefox (Gecko) qui proposent NPAPI, et une couche logicielle transmet les appels de l’API vers le processus central de Firefox. Cette couche s’appelle IPDL (« Intercommunication Protocol Definition Language ») et transmet les appels via un socket Unix et une mémoire partagée sur Linux.

3. Firefox OS : Une opportunité qui ne se refuse pas !

Firefox OS est apparu plus récemment, basé sur le moteur de Firefox, Gecko.

Sous Firefox OS, chaque application peut se comparer à une fenêtre ou un onglet du navigateur éponyme.

Seulement, les applications n’ont pas besoin de partager le même set de cookies, mots de passe, etc. Elles n’ont pas non plus besoin de charger de plug-ins externes. Cela rend l’utilisation et la mise en œuvre de processus séparés beaucoup plus simple que dans le navigateur Firefox, car peu de données sont partagées entre les applications web.

En tant qu’applications à part entière, elles se doivent aussi d’être séparées par notre cher MMU et son mécanisme de mémoire protégée : une application ne doit pas pouvoir affecter une autre application ou planter le système, évidemment.

Pour toutes ces raisons, la séparation multiprocessus du moteur de rendu de contenu, et la sandbox ont d’abord été testées et introduites dans Firefox OS avant d’être actives sous Firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=790923).

3.1 Le modèle multiprocessus de Firefox OS et Firefox

Sous Firefox OS, un processus appelé b2g (« boot to gecko ») est lancé au démarrage du système. Ce processus est l’équivalent de Firefox, sauf qu’il démarre sa propre interface graphique au lieu d’ouvrir une fenêtre sur un système hôte (X11/GTK sur Linux, par exemple).

B2g lance aussi un premier processus qui affiche l’écran d’accueil et le lanceur d’applications de Firefox OS.

Lorsqu’une nouvelle application est lancée, b2g démarre un processus avec les arguments nécessaires, puis communique avec lui pour effectuer les actions privilèges via IPDL, tout comme les plug-ins hors processus – et utilise d’ailleurs le même code.

De fait, les processus application de Firefox OS sont les enfants (aussi appelés « child » ou « content-process ») de b2g, qui est lui appelé le processus parent. Ce processus parent tourne avec les droits administrateur (root).

Une grande partie du travail a été de convertir les appels aux fonctions de Firefox pour utiliser IPDL là où c’était nécessaire.

Le navigateur Firefox utilise le même modèle et le même code – mais pour le moment, utilise un processus pour l’interface graphique et un seul processus pour le rendu de contenu web.

Lorsque le contenu web, et donc le processus enfant a besoin d’un accès privilégié (« enregistrer un fichier sur le disque » ou « ouvrir une connexion TCP », par exemple) il doit le demander au processus parent via IPDL.

Le processus parent possède ses propres vérifications et ne donne accès qu’aux ressources, fichiers, etc. donc le contenu web peut avoir besoin. Ces vérifications sont programmées par les développeurs de Gecko.

Sous Firefox, par exemple lors de l’envoi de fichiers :

- le processus enfant ne peut accéder au fichier à envoyer, il demande donc au processus parent un fichier ;

- le processus parent ouvre une boite de dialogue et laisse l’utilisateur choisir le fichier à envoyer ;

- le processus parent ouvre ensuite le fichier choisi par l’utilisateur, et envoi le contenu (en fait, un pointeur vers un fichier ouvert) au processus enfant.

Il faut donc être très attentif au code IPDL et à la gestion des accès par le processus parent. Lorsqu’un attaquant s’échappe de la sandbox, c’est en général en demandant un accès qui n’a pas correctement été vérifié par le processus parent, ou qui donne accès à une ressource privilégiée vulnérable (par exemple, un attaquant pourrait envoyer une commande au pilote graphique qui exploite une vulnérabilité du pilote).

4. Une Sandbox, c’est simple alors !

Le principe de fonctionnent de la sandbox est assez simple. La mise en œuvre, c'est une autre affaire !

En effet, les mécanismes du noyau Linux dont nous avons discuté doivent souvent être utilisés de concert pour obtenir une protection plus complète. D'autre part, l'ancien modèle de code représente des années de travail et il faut du temps pour le convertir, petit à petit.

Par conséquent, la sandbox devient de plus en plus restreinte et donc de plus en plus utile au fur et à mesure.

4.1 La séparation multi-utilisateur sous Firefox OS

Les processus qui tournent sous le même utilisateur bien qu’étant séparés par la mémoire protégée, peuvent communiquer ou modifier les fichiers entre eux. Évidemment, c’est un problème !

Sous Firefox OS, chaque processus application tourne sous un utilisateur différent. Le processus parent se duplique (« fork »), puis lance les applications en tant que nouvel utilisateur non privilégié (« app1 », « app2 », etc.).

Le noyau Linux gère donc les accès entre processus de différents utilisateurs, et par défaut ne permet pas à un processus qui tourne par exemple sous l’utilisateur « app1 » d’accéder, de communiquer ou de modifier les données d’un processus qui tourne avec l’utilisateur « app2 ». Les systèmes de fichiers montés sont aussi configurés de cette façon.

Fig. 1 : Modèle multiprocessus de Firefox OS.

4.1.1 Portage sur Firefox, le navigateur

Malheureusement, le mode multi-utilisateur est difficile à utiliser dans un environnement normal, pour le navigateur Firefox. En effet, même avec seulement deux utilisateurs (l’utilisateur qui lance le navigateur et celui qui fait tourner le contenu web), il faut un processus privilégié (root) pour changer d’utilisateur. Google Chrome et Chromium - le navigateur de Google - utilisent un binaire qui utilise l’attribut « setuid » dans ce cas. Setuid permet à n’importe quel utilisateur de lancer le programme qui possède cet attribut en tant qu'utilisateur root.

Cela nécessite les droits root lors de l’installation du programme.

De fait, le navigateur Firefox n’utilise pour le moment pas de sandbox multi-utilisateur.

L’utilisation des namespace sous un même utilisateur est en cours de développement comme une alternative possible - qui ne nécessite pas les privilèges de l’utilisateur root - mais nécessite un noyau Linux récent.

4.2 Utilisation de Seccomp

Seccomp est utilisé dans le navigateur Firefox tout comme Firefox OS avec le même code.

Seuls les processus enfants (« content-processes ») utilisent seccomp.

Comme il est possible de démarrer seccomp à n’importe quel moment, cela facilite grandement la tâche sur un programme qui n'était à la base pas prévu pour faire tourner une sandbox. Sur Firefox, les fichiers nécessaires au chargement de l’application sont lus et chargés en mémoire sans aucune restriction. Seccomp est actif juste avant que le programme soit prêt à charger une page ou application web, et les restrictions d'accès aux appels système (et donc aux ressources) sont appliquées uniquement à partir de cet instant.

Dans ses débuts, ce type de sandbox était uniquement actif sous Firefox OS et utilisait son propre code d’initialisation, et son propre programme de filtrage d’appels système. Le programme est une longue liste d’instructions qui sont envoyées au noyau et créées par macros, en C.

4.3 Améliorations et utilisation du compilateur de règles seccomp de Chromium

Plus récemment, le code de création de filtres du navigateur Google Chrome a été porté et est maintenant utilisé. Il est plus flexible et simplifie la modification du filtre d’appels système.

Le filtre d’appels système se doit d’ailleurs d'être le plus court possible : il ne doit autoriser que les appels système considérés suffisamment simples et ne donnant pas accès à des ressources supplémentaires.

Par conséquent, le filtre actuel n’est pas parfait. S’il l'était, seccomp mode 1 pourrait d’ailleurs être utilisé.

Exemple de filtre d'arguments de l'appel système « clock_gettime » avec le compilateur de règles :

 

Allow(SYSCALL_WITH_ARG(clock_gettime, 0, CLOCK_MONOTONIC, CLOCK_REALTIME));

4.3.1 Qualité du filtre d’accès

Il y a trois raisons principales pour ne pas avoir un filtre court et strict :

1 - Certaines opérations d'accès aux ressources doivent être très rapides, et la demande d'accès au processus parent via IPDL ajoute trop de latence.

2 - Le code provient d’un binaire recompilé qui ne peut pas être modifié.

3 - Le code de la fonctionnalité en question ne permet pas encore d’utiliser IPDL, le filtre autorise l'accès jusqu'à ce que le code soit corrigé ou changé. Cela permet de progresser vers une sandbox plus stricte au fur et à mesure.

Lorsque l’on utilise le mode multi-utilisateur et seccomp de concert, les imperfections du filtre seccomp ne sont pas un problème, puisque le mode multi-utilisateur se charge de séparer l'accès aux ressources entre processus.

Le mode seccomp sert alors à réduire l'accès aux appels système, et donc au noyau. Cela réduit la possibilité pour un attaquant d’utiliser une vulnérabilité qui serait présente dans le noyau.

À voir, le filtre utilisé actuellement : http://hg.mozilla.org/mozilla-central/file/5438e3f74848/security/sandbox/linux/SandboxFilter.cpp et le suivi de l'amélioration du filtre :

https://wiki.mozilla.org/Security/Sandbox#Permissions_burndown_2.

4.3.2 Collaboration avec les développeurs de Chromium

Chromium, Chromium OS, Firefox et Firefox OS utilisent donc à présent un code similaire pour gérer les règles de la sandbox. Cela permet aussi de concentrer les efforts sur des problèmes identiques. Tout ceci étant open source, il est possible de partager les améliorations et de développer la sandbox plus rapidement.

Les équipes des deux navigateurs se rencontrent de temps en temps afin de faire le point et discuter de l’avenir de la sandbox, comme avec l’utilisation des namespaces par exemple.

5. L'avenir de la sandbox sur Firefox

L'utilité et la qualité de protection de la sandbox sont donc directement liées à l’architecture du code du navigateur.

La sandbox sert à contrôler les accès aux ressources entre processus, donc plus les composants du navigateur sont séparés, plus il est facile de les isoler dans des processus différents et d’avoir une liste de règles d'accès courte.

D’autre part, certains composants de code complexes tournent aujourd’hui dans le processus parent, qui possède le plus de privilèges. Ceux-ci peuvent être déplacés au fur et à mesure dans les processus non privilégiés. De ce fait, toute vulnérabilité dans le code sera mieux protégée par la sandbox.

Pour Firefox OS, le processus privilégié permet aussi de mettre à jour le système, redémarrer, charger les modules noyau, etc. Il existe un projet appelé « supervisor » dont le but est d'utiliser un 3ème processus très privilégié au-dessus du processus parent :

Fig. 2 : Supervisor.

Une grande partie du travail restant est donc de séparer les anciens composants, comme le moteur et pilote graphique et l'accès à certains fichiers. Une autre séparation très intéressante se trouve entre les différents sites web (fichiers chargés depuis un nom de domaine) qui sont chargés par le navigateur. Cela permet d'empêcher à un site d'accéder aux cookies, documents HTML, mots de passe, permissions spécifiques aux pages (comme la caméra ou la localisation), etc. d’un autre site.

Le principe de séparation et communication entre éléments devient de plus en plus utilisé. Le noyau Linux permet non seulement de restreindre les accès aux ressources, mais aussi de gérer leur utilisation : par exemple, un processus peut être limité en taille mémoire, utilisation CPU, utilisation réseau.

Le modèle de séparation utilisé et le système de message sont très importants pour choisir le meilleur compromis entre performances, fonctionnalités et sécurité et sont étudiés, développés et mis en œuvre par de plus en plus de programmes.