De nombreuses applications Web doivent afficher du contenu contrôlé par l'utilisateur. Il peut s'agir d'une tâche simple, comme la diffusion d'images importées par l'utilisateur (par exemple, des photos de profil), ou d'une tâche complexe, comme l'affichage du code HTML contrôlé par l'utilisateur (par exemple, un tutoriel de développement Web). Cela a toujours été difficile à réaliser de manière sécurisée. Nous avons donc travaillé pour trouver des solutions simples, mais sécurisées, qui peuvent être appliquées à la plupart des types d'applications Web.
Solutions classiques pour isoler le contenu non approuvé
La solution classique pour diffuser des contenus contrôlés par l'utilisateur de manière sécurisée consiste à utiliser ce que l'on appelle des domaines de bac à sable. L'idée de base est que si le domaine principal de votre application est example.com
, vous pouvez diffuser tous les contenus non approuvés sur exampleusercontent.com
. Étant donné que ces deux domaines sont intersites, tout contenu malveillant sur exampleusercontent.com
ne peut pas avoir d'incidence sur example.com
.
Cette approche permet de diffuser en toute sécurité tous types de contenus non approuvés, y compris des images, des téléchargements et du code HTML. Bien que cela ne semble pas nécessaire pour les images ou les téléchargements, cela permet d'éviter les risques liés au reniflage de contenu, en particulier dans les anciens navigateurs.
Les domaines de bac à sable sont largement utilisés dans le secteur et fonctionnent bien depuis longtemps. Toutefois, elles présentent deux inconvénients majeurs:
- Les applications doivent souvent limiter l'accès au contenu à un seul utilisateur, ce qui nécessite d'implémenter l'authentification et l'autorisation. Étant donné que les domaines de bac à sable ne partagent pas intentionnellement de cookies avec le domaine de l'application principale, cette opération est très difficile à effectuer de manière sécurisée. Pour prendre en charge l'authentification, les sites doivent soit s'appuyer sur des URL de capacité, soit définir des cookies d'authentification distincts pour le domaine du bac à sable. Cette deuxième méthode est particulièrement problématique sur le Web moderne, où de nombreux navigateurs limitent les cookies intersites par défaut.
- Bien que le contenu utilisateur soit isolé du site principal, il ne l'est pas des autres contenus utilisateur. Cela crée le risque que du contenu utilisateur malveillant attaque d'autres données sur le domaine de bac à sable (par exemple, en lisant des données d'origine commune).
Il est également intéressant de noter que les domaines de bac à sable permettent d'atténuer les risques de hameçonnage, car les ressources sont clairement segmentées sur un domaine isolé.
Solutions modernes pour diffuser du contenu utilisateur
Au fil du temps, le Web a évolué, et il existe désormais des moyens plus simples et plus sécurisés de diffuser du contenu non approuvé. Il existe de nombreuses approches différentes. Nous allons donc décrire deux solutions actuellement largement utilisées chez Google.
Méthode 1: Diffuser le contenu des utilisateurs inactifs
Si un site ne doit diffuser que du contenu utilisateur inactif (c'est-à-dire du contenu qui n'est pas HTML ni JavaScript, par exemple des images et des téléchargements), il peut désormais le faire en toute sécurité sans domaine de bac à sable isolé. Il existe deux étapes clés:
- Définissez toujours l'en-tête
Content-Type
sur un type MIME bien connu, compatible avec tous les navigateurs et qui ne contient pas de contenu actif (en cas de doute,application/octet-stream
est un choix sûr). - De plus, définissez toujours les en-têtes de réponse ci-dessous pour vous assurer que le navigateur isole complètement la réponse.
En-tête de réponse | Purpose |
---|---|
X-Content-Type-Options: nosniff |
Empêche le reniflage de contenu |
Content-Disposition: attachment; filename="download" |
Déclenche un téléchargement plutôt qu'un rendu |
Content-Security-Policy: sandbox |
Place le contenu dans un bac à sable comme s'il était diffusé sur un domaine distinct. |
Content-Security-Policy: default-src ‘none' |
Désactive l'exécution JavaScript (et l'inclusion de toute sous-ressource). |
Cross-Origin-Resource-Policy: same-site |
Empêche l'inclusion de la page entre les sites |
Cette combinaison d'en-têtes garantit que la réponse ne peut être chargée que comme sous-ressource par votre application ou téléchargée en tant que fichier par l'utilisateur. De plus, les en-têtes offrent plusieurs niveaux de protection contre les bugs du navigateur via l'en-tête de bac à sable CSP et la restriction default-src
. De manière générale, la configuration décrite ci-dessus offre un haut niveau de confiance quant à la probabilité que les réponses diffusées de cette manière ne puissent pas entraîner de failles d'injection ou d'isolation.
Défense en profondeur
Bien que la solution ci-dessus représente une défense généralement suffisante contre les attaques XSS, vous pouvez appliquer un certain nombre de mesures de renforcement supplémentaires pour fournir des couches de sécurité supplémentaires:
- Définissez un en-tête
X-Content-Security-Policy: sandbox
pour la compatibilité avec IE11. - Définissez un en-tête
Content-Security-Policy: frame-ancestors 'none'
pour empêcher l'intégration du point de terminaison. - Contenu utilisateur du bac à sable sur un sous-domaine isolé :
- Diffusion de contenu utilisateur sur un sous-domaine isolé (par exemple, Google utilise des domaines tels que
product.usercontent.google.com
). - Définissez
Cross-Origin-Opener-Policy: same-origin
etCross-Origin-Embedder-Policy: require-corp
pour activer l'isolation multi-origine.
- Diffusion de contenu utilisateur sur un sous-domaine isolé (par exemple, Google utilise des domaines tels que
Méthode 2: Diffuser du contenu pour les utilisateurs actifs
Vous pouvez également diffuser du contenu actif de manière sécurisée (par exemple, des images HTML ou SVG) sans les points faibles de l'approche classique du domaine de bac à sable.
L'option la plus simple consiste à utiliser l'en-tête Content-Security-Policy: sandbox
pour indiquer au navigateur d'isoler la réponse. Bien que tous les navigateurs Web n'implémentent pas actuellement l'isolation de processus pour les documents de bac à sable, les améliorations continues des modèles de processus de navigateur devraient améliorer la séparation du contenu en bac à sable des applications d'intégration. Si les attaques SpectreJS et de compromis du moteur de rendu ne font pas partie de votre modèle de menace, l'utilisation d'un bac à sable CSP est probablement une solution suffisante.
Chez Google, nous avons développé une solution capable d'isoler complètement le contenu actif non approuvé en modernisant le concept de domaines de bac à sable. L'idée de base est la suivante:
- Créez un domaine de bac à sable qui est ajouté à la liste de suffixes publics. Par exemple, en ajoutant
exampleusercontent.com
au fichier PSL, vous pouvez vous assurer quefoo.exampleusercontent.com
etbar.exampleusercontent.com
sont intersites et donc totalement isolés l'un de l'autre. - Les URL correspondant à
*.exampleusercontent.com/shim
sont toutes acheminées vers un fichier de shim statique. Ce fichier de shim contient un court extrait HTML et JavaScript qui écoute le gestionnaire d'événementsmessage
et affiche tout contenu qu'il reçoit. - Pour ce faire, le produit crée un iframe ou une fenêtre pop-up pour
$RANDOM_VALUE.exampleusercontent.com/shim
et utilisepostMessage
pour envoyer le contenu non approuvé au shim pour l'affichage. - Le contenu affiché est converti en blob et affiché dans un iFrame en bac à sable.
Par rapport à l'approche classique du bac à sable, cela garantit que tout le contenu est entièrement isolé sur un site unique. En laissant l'application principale gérer la récupération des données à afficher, il n'est plus nécessaire d'utiliser d'URL de capacité.
Conclusion
Ces deux solutions permettent de migrer depuis des domaines de bac à sable classiques tels que googleusercontent.com
vers des solutions plus sécurisées compatibles avec le blocage des cookies tiers. Chez Google, nous avons déjà migré de nombreux produits vers ces solutions, et nous prévoyons d'en migrer d'autres l'année prochaine.