Februar 20, 2022

Single Page Application absichern

OIDC WebApps und Token Handler

Das Web unterliegt einer ständigen Evolution, es entwickelt sich weiter, nicht nur in der Hardware und neuen Formaten, auch in der Art der Präsentation von Content. Mittlerweile wird die herkömmliche Architektur monolithischer Backends, die Businesslogik beinhalten und Content als HTML aufbereitet an einen Browser senden durch Single Page Applikationen (SPA) und Microservices im Backend ersetzt. Das hat erhebliche Auswirkungen auf die Sicherheitsarchitektur von Anwendungen und erfordert ein tiefgreifendes Verständnis der verwendeten Protokolle sowie des Handlings der Token und potenzieller Angriffsvektoren. Insbesondere, da Browser, in denen auch die SPA ablaufen, noch immer das Token Handling nicht unterstützen und Protokolle wir OAuth und OIDC für native Apps entwickelt wurden.

Background

Die Idee bei diesen Protokollen ist, dass die App das Token eigentlich nur dann bekommt, wenn Sie es benötigt, um auf eine API zuzugreifen und Daten abzurufen oder zu schreiben. Da das Access Token eine sehr kurze Gültigkeit hat, ist die Wahrscheinlichkeit eines Angriffs stark eingeschränkt und die Auswirkungen sind überschaubar. Da Handling des Tokens und die Flows werden über einen separaten Client erledigt, der nicht in der App integriert ist. Er läuft separiert.

Bei Java Script Apps, die in einem Browser laufen lässt, sich das nur schwierig darstellen, weshalb hier auch gerne auf den Implicit Flow zurückgegriffen wird. Dieser ist aber unsicher und sollte daher auch nicht verwendet werden, wie ich schon hier erläutert haben.

Cookies und Sicherheit

In traditionellen Web-Anwendungen wird die Security im Wesentlichen über spezielle Token, Cookie genannt, gehandhabt. Diese Cookies werden vom Browser verwaltet und vom Backend gesetzt. Normalerweise können Cookies auch nur an das Backend zurückgegeben werden, von dem sie gesetzt wurden. Dadurch verhindert der Browser das „Klauen“ der sicherheitsrelevanten Informationen. Browser kennen eine ganze Reihe von Policies, die die Verwendung von Cookies sicher machen.

Das Cookie wird mit jedem Request des Browsers an das Backend gesendet und kann somit die Anfrage Authentisieren sowie den Session Kontext im Backend herstellen. Es ist dabei unerheblich, ob das Backend monolithisch ist oder aus Microservices besteht. Bei SPA und Microservices muss in der Backendarchitektur sichergestellt werden, dass die Identität gegenüber den Services konsistent ist, sofern sie denn für die Anfrage benötigt wird. Das wird oft durch einen zentralen Identity Service realisiert. Auch der Reverse Proxy kann diesen Service bereitstellen und die Identität als Header oder Token an die Backend Anwendung weitergeben.

SPA, API und Microservices

Eine SPA hat normalerweise kein dezidiertes Backend. Der Code selbst ist kein HTML, das vom Browser gerendert und angezeigt wird, sondern JavaScript, Stylesheets, Bilder, etc. Das bedeutet auch, dass der Code zunächst geladen werden muss, bevor die Anwendung vom User benutzt werden kann. Für die Auslieferung wird oft ein Content Delivery Network (CDN) eingesetzt, sie hat also mit dem Backend Services zunächst nichts zu tun und ist völlig unabhängig. Die Anwendung kommuniziert dann mit einer API um Daten zu abzurufen bzw. auch zu speichern.

Da es kein dezidiertes Backend gibt, dass die Session der Anwendung mit dem Backend verwaltet, kann hier nicht mit einem Cookie gearbeitet werden. Stattdessen werden Access Token eingesetzt, um der Anwendung zu erlauben Daten für den Nutzer über die API abzurufen. Das Prinzip ist bereits im Artikel OAuth 4 Dummies like us und den folgenden diskutiert und erläutert.

OAuth2.0, OpenID Connect (OIDC) und JWT (Json Web Token) sind gängige Standards für den Einsatz von Token. Vom Einsatz proprietärer Lösungen wird abgeraten, aus Sicherheits- aber auch Kompatibilitätsgründen.

SPA und Security

Die Herausforderung beim Umstieg von Cookies auf Token besteht im Handling. Die Anwendung läuft in einer unsicheren Umgebung, dem Browser des Anwenders. Bei herkömmlichen WEB-Anwendungen ist der Browser ausschließlich die Display Ebene, die Logik selbst wird im Backend ausgeführt. Die Anwendung benötigt Token um Daten für den Nutzer abzurufen. Sehr oft sind zudem auch Refresh Token im Spiel, mit der Die Anwendung für einen langen Zeitraum ohne Eingriff des Anwenders neue Access Token erlangen kann. Weil die Credentials für die App lesbar sind, sind sie anfällig für Cross-Site Scripting Angriffe (XSS).

Jeder Code, der im Kontext der SPA läuft, hat Zugriff auf Access und Refresh Token. Der Angriffsvektor kann über den Browser Storage oder eine http Interception erfolgen. Mit diesem Token können Angreifer auch Daten erlangen, die durch die Logik der Anwendung nicht angezeigt würden, von der API aber bereitgestellt werden. Zudem kann mit dem Refresh Token Zugriff auf die API erlangt werden, auch wenn der Anwender sich bereits den Browser geschlossen hat. Kann der Angreifern den refresh Token extrahieren, kann er mit diesem Token über seine eigene App auf die API zugreifen und alle mit dem Token erlaubten Aktionen durchführen. Eventuelle Einschränkungen der App sind dann nicht mehr vorhanden.

Da aktuelle Browser der App keine Option bieten das Token sicher zu handhaben, sind XSS Angriffe für SPA extrem gefährlich. Entwickler sollten entsprechend großes Augenmerk darauf legen die SPA weitgehend vor XSS Angriffen zu schützen.

Ein weiteres Problem für SPA ist, dass Third Party Cookies von vielen Browsern nicht weiter unterstützt werden. Abhilfe schafft die Origin Policy, mit der das Backend definiert, an welche Domain das Cookie ausgeliefert werden darf. SPA’s nutzen Cookies oft um z.B. Refresh Token verschlüsselt abzulegen.

Session Cookies und Sicherheit

Auch Cookie basierte Web Anwendungen sind anfällig für XSS Vektoren. Ein Script kann z.B. kein http-only Cookies (in denen die Session ID gespeichert ist) zugreifen und in einer Anfrage verwenden. Die Cookies werden ausschließlich vom Browser an den Request angefügt.

Der Angriffsvektor basiert hier daher darauf aus dem Browser Aufrufe zum Backend zu generieren und die zurückgelieferten Daten auszuwerten. Das funktioniert nur solange der Browser geöffnet und die Session aktiv ist. Auch Cross-Site Request Fogerty (CSRF) Angriffe sind möglich und müssen verhindert werden.

Mit der Einführung von Content Security Policy (CSP) und dem Secure Flag bei Cookies sowie Mechanismen zur Eingrenzung von Domains, von denen Dokumente geladen werden dürfen (Cross-Origin Resource Sharing CORS)erhöhen die Sicherheit von Cookie basierten Anwendungen in einem Browser deutlich und unterstützen auch Apps im Browser. Für Entwickler ist es daher wichtig diese Mechanismen zu kennen und anzuwenden, um sichere SPA zu auszuliefern.

Optionen für sichere SPA

Aktuell ist es für SPA sehr schwierig bis unmöglich Token vor ungewünschten Zugriffen zu schützen. Auch wenn die Entwickler alle notwendigen Vorkehrungen gegen XSS Angriffe treffen, kann es immer noch durch Lücken in Third Party Libraries kommen. Der einzige sichere Weg Token vor unerwünschtem Zugriff zu schützen, ist sie gar nicht erst im Browser zu verwenden.

Die kann über eine Komponente im Backend realisiert werden, die das Token für die Anwendung handhabt und dafür Cookies ausstellt. Für eine SPA bedeutet das der Zugang zur API erfolgt über einen Token Handler. Dabei übernimmt der Token Handler die OAuth/OIDC Flows und stellt gegenüber dem Frontend, der SPA, Cookies aus.

Bei diesem Ansatz erreicht kein Token die SPA und müssen dort auch nicht gehandhabt werden. Der Code für den Token Handler läuft nicht im Browser oder auf dem PC des Anwenders, sondern zentral auf dem Reverse Proxy oder dem API Gateway. Die SPA erhält anstelle dessen einen Session Cookie, der vom Browser gehandhabt wird. Obwohl somit eine SPA im Browser läuft, kann die Sicherheit gleich einer Browseranwendung erreicht werden.

Da der OAuth Client nun in einer sicheren Umgebung läuft können auch einfache Flows wie der Client Credential Flow in Betracht gezogen werden, um Token zu beziehen.

Zusammenfassung

Die Implementierung von Token Proxies für eine SPA ist ein guter Weg die Sicherheit zu erhöhen. Der Proxy verhindert nicht alle denkbaren Angriffe, allerdings reduzieren sich die Vektoren auf die einer Browser basierten Webseite. Die Vektoren sind deutlich besser bekannt und können mit modernen Browsern weitgehend verhindert werden.

Es ist daher sinnvoll Token komplett aus dem Browser fernzuhalten, solange diese keine Möglichkeit für das sichere Token Handling anbieten. Soll dennoch das Handling in der SPA implementiert werden ist unbedingt auf einen separaten Client zu setzen, der nicht im Main Code der Applikation eingebettet ist.

Dies ist der erste Artikel einer Reihe, in der ich SPA und Token basierte Zugriffe auf eine API betrachte. Weitere werden folgen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

DSGVO Cookie Consent mit Real Cookie Banner