De nombreuses applications Web doivent afficher du contenu contrôlé par l'utilisateur. Cela peut être aussi simple que de diffuser des images importées par l'utilisateur (par exemple, des photos de profil) ou aussi complexes que d'afficher du code HTML contrôlé par l'utilisateur (par exemple, un tutoriel de développement Web). Cela a toujours été difficile à faire de manière sécurisée. C'est pourquoi nous nous sommes efforcés de trouver des solutions simples, mais sécurisées, applicables à la plupart des types d'applications Web.
Les solutions classiques pour isoler les contenus non fiables
La solution classique pour diffuser de manière sécurisée du contenu contrôlé par l'utilisateur 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 tout le contenu non approuvé sur exampleusercontent.com
. Ces deux domaines étant intersites, tout contenu malveillant disponible sur exampleusercontent.com
ne peut pas avoir d'impact sur example.com
.
Cette approche peut être utilisée pour diffuser en toute sécurité tous types de contenus non fiables, y compris des images, des téléchargements et du code HTML. Même s'il ne semble pas nécessaire de l'utiliser 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 restreindre l'accès au contenu à un seul utilisateur, ce qui nécessite de mettre en œuvre une authentification et une autorisation. Étant donné que les domaines de bac à sable ne partagent volontairement pas de cookies avec le domaine d'application principal, il est très difficile d'effectuer cette opération en toute sécurité. Pour accepter l'authentification, les sites doivent soit s'appuyer sur des URL "capability", soit définir des cookies d'authentification distincts pour le domaine de bac à sable. Cette seconde méthode est particulièrement problématique sur le Web moderne, où de nombreux navigateurs limitent par défaut les cookies intersites.
- Bien que le contenu de l'utilisateur soit isolé du site principal, il ne l'est pas des autres contenus des utilisateurs. Cela crée un risque que du contenu utilisateur malveillant attaque d'autres données du domaine de bac à sable (par exemple, en lisant des données d'origine identique).
Il convient également de noter que les domaines de bac à sable permettent de réduire les risques d'hameçonnage, car les ressources sont clairement segmentées en 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 des contenus non approuvés. Il existe de nombreuses approches différentes. Nous allons donc vous présenter deux solutions qui sont largement utilisées actuellement chez Google.
Méthode 1: diffuser du contenu destiné aux utilisateurs inactifs
Si un site a uniquement besoin de diffuser du contenu utilisateur inactif (c'est-à-dire du contenu autre que HTML ou JavaScript, par exemple des images et des téléchargements), vous pouvez désormais le faire en toute sécurité sans domaine de bac à sable isolé. Il y a deux étapes principales:
- Définissez toujours l'en-tête
Content-Type
sur un type MIME bien connu, compatible avec tous les navigateurs et sans contenu actif (en cas de doute,application/octet-stream
constitue 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 que l'affichage |
Content-Security-Policy: sandbox |
Applique le bac à sable au contenu comme s'il avait été diffusé sur un domaine distinct. |
Content-Security-Policy: default-src ‘none' |
Désactive l'exécution JavaScript (et l'inclusion de toutes les sous-ressources) |
Cross-Origin-Resource-Policy: same-site |
Empêche l'inclusion de la page sur plusieurs sites |
Cette combinaison d'en-têtes garantit que la réponse ne peut être chargée qu'en tant que sous-ressource par votre application, ou téléchargée en tant que fichier par l'utilisateur. De plus, les en-têtes fournissent plusieurs couches de protection contre les bugs du navigateur via l'en-tête du bac à sable CSP et la restriction default-src
. Globalement, la configuration décrite ci-dessus garantit avec une grande certitude que les réponses diffusées de cette manière ne peuvent 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, il existe un certain nombre de mesures de renforcement supplémentaires que vous pouvez appliquer pour fournir des niveaux de sécurité supplémentaires:
- Définissez un en-tête
X-Content-Security-Policy: sandbox
pour assurer 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. - les contenus des utilisateurs du bac à sable sur un sous-domaine isolé:
<ph type="x-smartling-placeholder">
- </ph>
- Diffuser du 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.
- Diffuser du contenu utilisateur sur un sous-domaine isolé (par exemple, Google utilise des domaines tels que
Méthode 2: diffuser le contenu des 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 ne mettent pas actuellement en œuvre l'isolation de processus pour les documents de bac à sable, les améliorations continues apportées aux modèles de processus du navigateur sont susceptibles d'améliorer la séparation entre le contenu de bac à sable et les applications intégrées. Si les attaques SpectreJS et de compromission du moteur de rendu ne font pas partie de votre modèle de menaces, l'utilisation du bac à sable CSP est probablement une solution suffisante.
Chez Google, nous avons développé une solution permettant d'isoler complètement le contenu actif non approuvé en modernisant le concept des domaines de bac à sable. L'idée centrale est la suivante:
- Créez un domaine de bac à sable qui est ajouté à la liste des suffixes publics. Par exemple, en ajoutant
exampleusercontent.com
au PSL, vous pouvez vous assurer quefoo.exampleusercontent.com
etbar.exampleusercontent.com
sont intersites et donc totalement isolés. - Les URL correspondant à
*.exampleusercontent.com/shim
sont toutes routées vers un fichier correctif statique. Ce fichier shim contient un court extrait de code HTML et JavaScript qui écoute le gestionnaire d'événementsmessage
et affiche le contenu qu'il reçoit. - Pour utiliser cette option, le produit crée un iFrame ou un pop-up dans
$RANDOM_VALUE.exampleusercontent.com/shim
et utilisepostMessage
pour envoyer le contenu non approuvé au shim pour qu'il s'affiche. - Le contenu affiché est transformé en blob et affiché dans un iFrame en bac à sable.
Par rapport à l'approche classique du domaine de bac à sable, cela garantit que tout le contenu est entièrement isolé sur un site unique. De plus, comme l'application principale doit récupérer les données à afficher, il n'est plus nécessaire d'utiliser des URL de capacité.
Conclusion
Ensemble, ces deux solutions permettent de migrer 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 afin d'utiliser ces solutions et nous prévoyons d'autres migrations pour l'année prochaine.