Sicheres Hosting von Nutzerdaten in modernen Webanwendungen

David Dworken
David Dworken

Viele Webanwendungen müssen nutzergesteuerte Inhalte anzeigen. Das kann so einfach sein wie das Bereitstellen von Bildern, die von Nutzern hochgeladen wurden (z. B. Profilbilder), oder eine komplexe Angelegenheit wie das Rendern von nutzergesteuertem HTML (z. B. eine Anleitung zur Webentwicklung). Dies war immer schwierig und sicher. Daher haben wir daran gearbeitet, einfache, aber sichere Lösungen zu finden, die auf die meisten Arten von Webanwendungen angewendet werden können.

Klassische Lösungen zum Isolieren nicht vertrauenswürdiger Inhalte

Die klassische Lösung für die sichere Bereitstellung von nutzergesteuerten Inhalten sind sogenannte Sandbox-Domains. Die Grundidee ist, dass, wenn die Hauptdomain Ihrer Anwendung example.com ist, alle nicht vertrauenswürdigen Inhalte auf exampleusercontent.com bereitgestellt werden können. Da diese beiden Domains websiteübergreifend sind, haben schädliche Inhalte auf exampleusercontent.com keine Auswirkungen auf example.com.
Auf diese Weise können alle Arten von nicht vertrauenswürdigen Inhalten wie Bilder, Downloads und HTML sicher bereitgestellt werden. Auch wenn es nicht unbedingt notwendig erscheint, diese Funktion für Bilder oder Downloads zu verwenden, sollten Sie so das Risiko des Sniffing von Inhalten vermeiden, insbesondere in älteren Browsern.
Sandbox-Domains sind in der Branche weit verbreitet und funktionieren seit Langem gut. Allerdings haben sie zwei wesentliche Nachteile:

  • Anwendungen müssen den Zugriff auf Inhalte häufig auf einen einzelnen Nutzer beschränken. Dafür müssen eine Authentifizierung und Autorisierung implementiert werden. Da Sandbox-Domains absichtlich keine Cookies mit der Haupt-Domain der Anwendung teilen, ist dies sehr schwierig, sicher. Zur Unterstützung der Authentifizierung müssen Websites entweder Funktions-URLs nutzen oder separate Authentifizierungscookies für die Sandbox-Domain setzen. Diese zweite Methode ist besonders im modernen Web problematisch, wo viele Browser websiteübergreifende Cookies standardmäßig einschränken.
  • Während der Nutzerinhalt von der Hauptwebsite isoliert ist, ist er nicht von anderen Nutzerinhalten isoliert. Dadurch besteht das Risiko, dass schädliche Nutzerinhalte andere Daten in der Sandbox-Domain angreifen (z. B. durch Lesen von Daten aus demselben Ursprung).

Sandbox-Domains tragen außerdem dazu bei, das Phishing-Risiko zu mindern, da die Ressourcen klar in eine isolierte Domain unterteilt sind.

Moderne Lösungen zum Bereitstellen von Nutzerinhalten

Im Laufe der Zeit hat sich das Web weiterentwickelt und es gibt jetzt einfachere und sicherere Möglichkeiten, nicht vertrauenswürdige Inhalte bereitzustellen. Dabei gibt es viele verschiedene Ansätze. Daher werden wir zwei Lösungen vorstellen, die bei Google derzeit weit verbreitet sind.

Methode 1: Inaktive Nutzerinhalte bereitstellen

Wenn eine Website nur inaktive Nutzerinhalte bereitstellen muss, d. h. Inhalte, bei denen es sich nicht um HTML- oder JavaScript-Inhalte handelt, z. B. Bilder und Downloads, ist dies jetzt ohne isolierte Sandbox-Domain möglich. Dazu sind zwei wichtige Schritte erforderlich:

  • Setzen Sie den Content-Type-Header immer auf einen bekannten MIME-Typ, der von allen Browsern unterstützt wird und garantiert keine aktiven Inhalte enthält. Im Zweifelsfall ist application/octet-stream eine sichere Wahl.
  • Legen Sie außerdem immer die folgenden Antwortheader fest, um sicherzustellen, dass der Browser die Antwort vollständig isoliert.
Antwortheader Purpose

X-Content-Type-Options: nosniff

Verhindert das Sniffing

Content-Disposition: attachment; filename="download"

Löst einen Download statt eines Renderings aus

Content-Security-Policy: sandbox

Inhalte werden in einer Sandbox ausgeführt, als würden sie in einer separaten Domain bereitgestellt.

Content-Security-Policy: default-src ‘none'

Deaktiviert die JavaScript-Ausführung (und das Einbeziehen etwaiger Unterressourcen)

Cross-Origin-Resource-Policy: same-site

Verhindert, dass die Seite websiteübergreifend eingeschlossen wird

Durch diese Kombination von Headern wird sichergestellt, dass die Antwort von Ihrer Anwendung nur als Unterressource geladen oder vom Nutzer als Datei heruntergeladen werden kann. Darüber hinaus bieten die Header über den CSP-Sandbox-Header und die Einschränkung „default-src“ einen mehrschichtigen Schutz vor Browserfehlern. Insgesamt bietet die oben beschriebene Konfiguration ein hohes Maß an Sicherheit, dass auf diese Weise bereitgestellte Antworten nicht zu Injektions- oder Isolationsschwachstellen führen können.

Gestaffelte Sicherheitsebenen

Die obige Lösung stellt zwar eine allgemein ausreichende Abwehr gegen XSS dar, es gibt jedoch eine Reihe zusätzlicher Härtungsmaßnahmen, die Sie anwenden können, um zusätzliche Sicherheitsebenen zu schaffen:

  • Legen Sie einen X-Content-Security-Policy: sandbox-Header fest, um Kompatibilität mit IE11 zu ermöglichen.
  • Legen Sie einen Content-Security-Policy: frame-ancestors 'none'-Header fest, um das Einbetten des Endpunkts zu blockieren.
  • So können Sie Nutzerinhalte auf einer isolierten Subdomain in einer Sandbox ausführen: <ph type="x-smartling-placeholder">
      </ph>
    • Bereitstellung von Nutzerinhalten auf einer isolierten Subdomain (Google verwendet z.B. Domains wie product.usercontent.google.com).
    • Legen Sie Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp fest, um die ursprungsübergreifende Isolierung zu aktivieren.

Ansatz 2: Aktive Nutzerinhalte bereitstellen

Die sichere Bereitstellung aktiver Inhalte (z. B. HTML- oder SVG-Bilder) ist ebenfalls ohne die Schwächen der klassischen Sandbox-Domain möglich.
Die einfachste Möglichkeit besteht darin, den Content-Security-Policy: sandbox-Header zu nutzen, um den Browser anzuweisen, die Antwort zu isolieren. Obwohl nicht alle Webbrowser derzeit die Prozessisolierung für Sandbox-Dokumente implementieren, werden fortlaufende Optimierungen der Browserprozessmodelle wahrscheinlich die Trennung von Inhalten, die in einer Sandbox ausgeführt werden, von eingebetteten Anwendungen verbessern. Wenn SpectreJS- und Renderer-Manipulationsangriffe außerhalb Ihres Bedrohungsmodells stattfinden, ist die CSP-Sandbox wahrscheinlich eine ausreichende Lösung.
Google hat eine Lösung entwickelt, mit der nicht vertrauenswürdige aktive Inhalte vollständig isoliert werden können, indem das Konzept der Sandbox-Domains modernisiert wird. Die Kernidee ist:

  • Erstellen Sie eine neue Sandbox-Domain, die zur Liste der öffentlichen Suffixe hinzugefügt wird. Wenn Sie beispielsweise exampleusercontent.com zur PSL hinzufügen, können Sie dafür sorgen, dass foo.exampleusercontent.com und bar.exampleusercontent.com websiteübergreifend und somit vollständig voneinander isoliert sind.
  • Alle mit *.exampleusercontent.com/shim übereinstimmenden URLs werden an eine statische Shim-Datei weitergeleitet. Diese Shim-Datei enthält ein kurzes HTML- und JavaScript-Snippet, das den message-Event-Handler überwacht und alle empfangenen Inhalte rendert.
  • Dazu erstellt das Produkt entweder einen iFrame oder ein Pop-up für $RANDOM_VALUE.exampleusercontent.com/shim und verwendet postMessage, um die nicht vertrauenswürdigen Inhalte zum Rendern an den Shim zu senden.
  • Der gerenderte Inhalt wird in ein Blob umgewandelt und in einem in einer Sandbox ausgeführten iFrame gerendert.

Im Vergleich zum klassischen Sandbox-Domain-Ansatz wird so sichergestellt, dass alle Inhalte auf einer einzigen Website vollständig isoliert sind. Da die Hauptanwendung die zu rendernden Daten abruft, sind keine Funktions-URLs mehr erforderlich.

Fazit

Gemeinsam ermöglichen diese beiden Lösungen die Migration von klassischen Sandbox-Domains wie googleusercontent.com zu sichereren Lösungen, die mit der Blockierung von Drittanbieter-Cookies kompatibel sind. Wir bei Google haben bereits viele Produkte migriert, um diese Lösungen zu nutzen, und planen für das nächste Jahr weitere Migrationen.