Angular
Die Checkliste
Checkliste von hier.
Was ist Angular
Angular ist ein leistungsstarkes und Open-Source-Frontend-Framework, das von Google gepflegt wird. Es verwendet TypeScript, um die Lesbarkeit und das Debugging des Codes zu verbessern. Mit starken Sicherheitsmechanismen verhindert Angular gängige clientseitige Schwachstellen wie XSS und offene Weiterleitungen. Es kann auch auf der Server-Seite verwendet werden, was Sicherheitsüberlegungen aus beiden Perspektiven wichtig macht.
Framework-Architektur
Um die Grundlagen von Angular besser zu verstehen, lassen Sie uns seine wesentlichen Konzepte durchgehen.
Ein typisches Angular-Projekt sieht normalerweise so aus:
Laut der Dokumentation hat jede Angular-Anwendung mindestens eine Komponente, die Wurzelkomponente (AppComponent
), die eine Komponentenhierarchie mit dem DOM verbindet. Jede Komponente definiert eine Klasse, die Anwendungsdaten und -logik enthält und mit einer HTML-Vorlage verknüpft ist, die eine Ansicht definiert, die in einer Zielumgebung angezeigt werden soll. Der @Component()
-Dekorator identifiziert die direkt darunter liegende Klasse als Komponente und stellt die Vorlage sowie die zugehörigen komponentenspezifischen Metadaten bereit. Die AppComponent
ist in der Datei app.component.ts
definiert.
Angular NgModules erklären einen Kompilierungskontext für eine Gruppe von Komponenten, die einem Anwendungsbereich, einem Workflow oder einer eng verwandten Gruppe von Funktionen gewidmet sind. Jede Angular-Anwendung hat ein Wurzelmodul, das konventionell AppModule
genannt wird und den Bootstrap-Mechanismus bereitstellt, der die Anwendung startet. Eine Anwendung enthält typischerweise viele funktionale Module. Das AppModule
ist in der Datei app.module.ts
definiert.
Das Angular Router
NgModule bietet einen Dienst, der es Ihnen ermöglicht, einen Navigationspfad zwischen den verschiedenen Anwendungszuständen und Ansichtshierarchien in Ihrer Anwendung zu definieren. Das RouterModule
ist in der Datei app-routing.module.ts
definiert.
Für Daten oder Logik, die nicht mit einer bestimmten Ansicht verknüpft sind und die Sie über Komponenten hinweg teilen möchten, erstellen Sie eine Dienstklasse. Eine Dienstklassendefinition wird unmittelbar von dem @Injectable()
-Dekorator vorausgegangen. Der Dekorator stellt die Metadaten bereit, die es anderen Anbietern ermöglichen, als Abhängigkeiten in Ihre Klasse injiziert zu werden. Die Abhängigkeitsinjektion (DI) ermöglicht es Ihnen, Ihre Komponentenklassen schlank und effizient zu halten. Sie holen keine Daten vom Server, validieren keine Benutzereingaben oder protokollieren nicht direkt in die Konsole; sie delegieren solche Aufgaben an Dienste.
Sourcemap-Konfiguration
Das Angular-Framework übersetzt TypeScript-Dateien in JavaScript-Code, indem es die Optionen aus tsconfig.json
befolgt, und erstellt dann ein Projekt mit der Konfiguration aus angular.json
. Wenn wir die Datei angular.json
betrachten, haben wir eine Option beobachtet, um eine Sourcemap zu aktivieren oder zu deaktivieren. Laut der Angular-Dokumentation hat die Standardkonfiguration eine Sourcemap-Datei für Skripte aktiviert und ist standardmäßig nicht verborgen:
Generell werden Sourcemap-Dateien für Debugging-Zwecke verwendet, da sie generierte Dateien mit ihren ursprünglichen Dateien verknüpfen. Daher wird nicht empfohlen, sie in einer Produktionsumgebung zu verwenden. Wenn Sourcemaps aktiviert sind, verbessert sich die Lesbarkeit und unterstützt die Dateianalyse, indem der ursprüngliche Zustand des Angular-Projekts repliziert wird. Wenn sie jedoch deaktiviert sind, kann ein Prüfer eine kompilierte JavaScript-Datei manuell analysieren, indem er nach anti-sicherheitsmustern sucht.
Darüber hinaus kann eine kompilierte JavaScript-Datei mit einem Angular-Projekt in den Entwicklertools des Browsers → Quellen (oder Debugger und Quellen) → [id].main.js gefunden werden. Abhängig von den aktivierten Optionen kann diese Datei die folgende Zeile am Ende enthalten //# sourceMappingURL=[id].main.js.map
oder sie kann es nicht, wenn die hidden-Option auf true gesetzt ist. Dennoch wird das Testen komplexer, wenn die Sourcemap für Skripte deaktiviert ist, und wir können die Datei nicht erhalten. Darüber hinaus kann die Sourcemap während des Projektbaus aktiviert werden, wie ng build --source-map
.
Datenbindung
Binding bezieht sich auf den Prozess der Kommunikation zwischen einer Komponente und ihrer entsprechenden Ansicht. Es wird verwendet, um Daten an das Angular-Framework zu übertragen und von diesem zu empfangen. Daten können auf verschiedene Weise übergeben werden, z. B. durch Ereignisse, Interpolation, Eigenschaften oder durch den Mechanismus der bidirektionalen Bindung. Darüber hinaus können Daten auch zwischen verwandten Komponenten (Eltern-Kind-Beziehung) und zwischen zwei nicht verwandten Komponenten mithilfe der Service-Funktion geteilt werden.
Wir können Binding nach Datenfluss klassifizieren:
Datenquelle zu Zielansicht (einschließlich Interpolation, Eigenschaften, Attribute, Klassen und Stile); kann durch Verwendung von
[]
oder{{}}
im Template angewendet werden;Zielansicht zu Datenquelle (einschließlich Ereignisse); kann durch Verwendung von
()
im Template angewendet werden;Zwei-Wege; kann durch Verwendung von
[()]
im Template angewendet werden.
Binding kann auf Eigenschaften, Ereignisse und Attribute sowie auf jedes öffentliche Mitglied einer Quell-Direktive angewendet werden:
Property
Elementeigenschaft, Komponenteneigenschaft, Direktiveigenschaft
<img [alt]="hero.name" [src]="heroImageUrl">
Event
Elementereignis, Komponenteneignis, Direktiveereignis
<button type="button" (click)="onSave()">Speichern
Two-way
Ereignis und Eigenschaft
<input [(ngModel)]="name">
Attribute
Attribut (die Ausnahme)
<button type="button" [attr.aria-label]="help">hilfe
Class
Klassen-Eigenschaft
<div [class.special]="isSpecial">Spezial
Style
Stil-Eigenschaft
<button type="button" [style.color]="isSpecial ? 'red' : 'green'">
Angular-Sicherheitsmodell
Das Design von Angular umfasst standardmäßig die Kodierung oder Sanitärung aller Daten, was es zunehmend schwierig macht, XSS-Schwachstellen in Angular-Projekten zu entdecken und auszunutzen. Es gibt zwei verschiedene Szenarien für die Datenverarbeitung:
Interpolation oder
{{user_input}}
- führt kontextabhängige Kodierung durch und interpretiert Benutzereingaben als Text;
Ergebnis: <script>alert(1)</script><h1>test</h1>
2. Binding an Eigenschaften, Attribute, Klassen und Stile oder [attribute]="user_input"
- führt eine Sanitärung basierend auf dem bereitgestellten Sicherheitskontext durch.
Ergebnis: <div><h1>test</h1></div>
Es gibt 6 Typen von SecurityContext
:
None
;HTML
wird verwendet, wenn der Wert als HTML interpretiert wird;STYLE
wird verwendet, wenn CSS in diestyle
-Eigenschaft gebunden wird;URL
wird für URL-Eigenschaften verwendet, wie<a href>
;SCRIPT
wird für JavaScript-Code verwendet;RESOURCE_URL
als URL, die geladen und als Code ausgeführt wird, z. B. in<script src>
.
Schwachstellen
Umgehung der Sicherheitsvertrauensmethoden
Angular führt eine Liste von Methoden ein, um den standardmäßigen Sanitärungsprozess zu umgehen und anzuzeigen, dass ein Wert in einem bestimmten Kontext sicher verwendet werden kann, wie in den folgenden fünf Beispielen:
bypassSecurityTrustUrl
wird verwendet, um anzuzeigen, dass der angegebene Wert eine sichere Stil-URL ist:
bypassSecurityTrustResourceUrl
wird verwendet, um anzuzeigen, dass der angegebene Wert eine sichere Ressourcen-URL ist:
bypassSecurityTrustHtml
wird verwendet, um anzuzeigen, dass der angegebene Wert sicheres HTML ist. Beachten Sie, dass das Einfügen vonscript
-Elementen in den DOM-Baum auf diese Weise nicht dazu führt, dass der enthaltene JavaScript-Code ausgeführt wird, aufgrund der Art und Weise, wie diese Elemente zum DOM-Baum hinzugefügt werden.
bypassSecurityTrustScript
wird verwendet, um anzuzeigen, dass der angegebene Wert sicheres JavaScript ist. Wir fanden jedoch, dass sein Verhalten unvorhersehbar ist, da wir keinen JS-Code in Vorlagen mit dieser Methode ausführen konnten.
bypassSecurityTrustStyle
wird verwendet, um anzuzeigen, dass der angegebene Wert sicheres CSS ist. Das folgende Beispiel veranschaulicht CSS-Injection:
Angular bietet eine sanitize
-Methode, um Daten zu sanitärisieren, bevor sie in Ansichten angezeigt werden. Diese Methode verwendet den bereitgestellten Sicherheitskontext und reinigt die Eingabe entsprechend. Es ist jedoch entscheidend, den richtigen Sicherheitskontext für die spezifischen Daten und den Kontext zu verwenden. Beispielsweise bietet die Anwendung eines Sanitizers mit SecurityContext.URL
auf HTML-Inhalt keinen Schutz gegen gefährliche HTML-Werte. In solchen Szenarien könnte der Missbrauch des Sicherheitskontexts zu XSS-Schwachstellen führen.
HTML-Injection
Diese Schwachstelle tritt auf, wenn Benutzereingaben an eines der drei Eigenschaften gebunden werden: innerHTML
, outerHTML
oder iframe
srcdoc
. Während das Binden an diese Attribute HTML so interpretiert, wie es ist, wird die Eingabe mit SecurityContext.HTML
sanitärisiert. Daher ist HTML-Injection möglich, aber Cross-Site-Scripting (XSS) nicht.
Beispiel für die Verwendung von innerHTML
:
The result is <div><h1>test</h1></div>
.
Template injection
Client-Side Rendering (CSR)
Angular nutzt Templates, um Seiten dynamisch zu erstellen. Der Ansatz besteht darin, Template-Ausdrücke für Angular zur Auswertung in doppelte geschweifte Klammern ({{}}
) einzuschließen. Auf diese Weise bietet das Framework zusätzliche Funktionalität. Zum Beispiel würde ein Template wie {{1+1}}
als 2 angezeigt werden.
Typischerweise entkommt Angular Benutzereingaben, die mit Template-Ausdrücken verwechselt werden können (z. B. Zeichen wie `< > ' " ``). Das bedeutet, dass zusätzliche Schritte erforderlich sind, um diese Einschränkung zu umgehen, wie die Verwendung von Funktionen, die JavaScript-String-Objekte generieren, um die Verwendung von auf der Blacklist stehenden Zeichen zu vermeiden. Um dies zu erreichen, müssen wir jedoch den Angular-Kontext, seine Eigenschaften und Variablen berücksichtigen. Daher könnte ein Template-Injection-Angriff wie folgt aussehen:
Wie oben gezeigt, bezieht sich constructor
auf den Geltungsbereich der Objekt constructor
-Eigenschaft, was es uns ermöglicht, den String-Konstruktor aufzurufen und beliebigen Code auszuführen.
Server-Side Rendering (SSR)
Im Gegensatz zu CSR, das im DOM des Browsers stattfindet, ist Angular Universal für das SSR von Vorlagendateien verantwortlich. Diese Dateien werden dann an den Benutzer geliefert. Trotz dieser Unterscheidung wendet Angular Universal die gleichen Sanitization-Mechanismen an, die auch in CSR verwendet werden, um die Sicherheit von SSR zu verbessern. Eine Template-Injection-Sicherheitsanfälligkeit in SSR kann auf die gleiche Weise wie in CSR erkannt werden, da die verwendete Template-Sprache dieselbe ist.
Natürlich besteht auch die Möglichkeit, neue Template-Injection-Sicherheitsanfälligkeiten einzuführen, wenn Drittanbieter-Template-Engines wie Pug und Handlebars verwendet werden.
XSS
DOM-Schnittstellen
Wie bereits erwähnt, können wir direkt auf das DOM über die Document-Schnittstelle zugreifen. Wenn Benutzereingaben nicht vorher validiert werden, kann dies zu Cross-Site-Scripting (XSS)-Sicherheitsanfälligkeiten führen.
Wir haben die Methoden document.write()
und document.createElement()
in den folgenden Beispielen verwendet:
Angular-Klassen
Es gibt einige Klassen, die verwendet werden können, um mit DOM-Elementen in Angular zu arbeiten: ElementRef
, Renderer2
, Location
und Document
. Eine detaillierte Beschreibung der letzten beiden Klassen ist im Abschnitt Open redirects zu finden. Der Hauptunterschied zwischen den ersten beiden besteht darin, dass die Renderer2
-API eine Abstraktionsschicht zwischen dem DOM-Element und dem Komponenten-Code bereitstellt, während ElementRef
lediglich eine Referenz auf das Element hält. Daher sollte laut Angular-Dokumentation die ElementRef
-API nur als letztes Mittel verwendet werden, wenn direkter Zugriff auf das DOM erforderlich ist.
ElementRef
enthält die EigenschaftnativeElement
, die verwendet werden kann, um die DOM-Elemente zu manipulieren. Eine unsachgemäße Verwendung vonnativeElement
kann zu einer XSS-Injektionsanfälligkeit führen, wie unten gezeigt:
Trotz der Tatsache, dass
Renderer2
eine API bereitstellt, die sicher verwendet werden kann, selbst wenn direkter Zugriff auf native Elemente nicht unterstützt wird, hat es dennoch einige Sicherheitsmängel. MitRenderer2
ist es möglich, Attribute eines HTML-Elements mit der MethodesetAttribute()
festzulegen, die keine XSS-Präventionsmechanismen hat.
Um die Eigenschaft eines DOM-Elements festzulegen, können Sie die Methode
Renderer2.setProperty()
verwenden und einen XSS-Angriff auslösen:
Während unserer Forschung haben wir auch das Verhalten anderer Renderer2
-Methoden wie setStyle()
, createComment()
und setValue()
in Bezug auf XSS- und CSS-Injektionen untersucht. Wir konnten jedoch aufgrund ihrer funktionalen Einschränkungen keine gültigen Angriffsvektoren für diese Methoden finden.
jQuery
jQuery ist eine schnelle, kleine und funktionsreiche JavaScript-Bibliothek, die im Angular-Projekt verwendet werden kann, um bei der Manipulation der HTML-DOM-Objekte zu helfen. Wie bekannt ist, können die Methoden dieser Bibliothek ausgenutzt werden, um eine XSS-Anfälligkeit zu erreichen. Um zu diskutieren, wie einige anfällige jQuery-Methoden in Angular-Projekten ausgenutzt werden können, haben wir diesen Unterabschnitt hinzugefügt.
Die Methode
html()
erhält den HTML-Inhalt des ersten Elements in der Menge der übereinstimmenden Elemente oder setzt den HTML-Inhalt jedes übereinstimmenden Elements. Allerdings kann durch das Design jeder jQuery-Konstruktor oder jede Methode, die einen HTML-String akzeptiert, potenziell Code ausführen. Dies kann durch die Injektion von<script>
-Tags oder die Verwendung von HTML-Attributen, die Code ausführen, wie im Beispiel gezeigt, geschehen.
Die Methode
jQuery.parseHTML()
verwendet native Methoden, um den String in eine Menge von DOM-Knoten zu konvertieren, die dann in das Dokument eingefügt werden können.
Wie bereits erwähnt, führen die meisten jQuery-APIs, die HTML-Strings akzeptieren, Skripte aus, die im HTML enthalten sind. Die Methode jQuery.parseHTML()
führt keine Skripte im geparsten HTML aus, es sei denn, keepScripts
ist ausdrücklich true
. Es ist jedoch in den meisten Umgebungen immer noch möglich, Skripte indirekt auszuführen; zum Beispiel über das Attribut <img onerror>
.
Open redirects
DOM-Schnittstellen
Laut der W3C-Dokumentation werden die Objekte window.location
und document.location
in modernen Browsern als Aliase behandelt. Deshalb haben sie eine ähnliche Implementierung einiger Methoden und Eigenschaften, die einen offenen Redirect und DOM-XSS mit javascript://
-Schema-Angriffen verursachen können, wie unten erwähnt.
window.location.href
(unddocument.location.href
)
Der kanonische Weg, um das aktuelle DOM-Standortobjekt zu erhalten, ist die Verwendung von window.location
. Es kann auch verwendet werden, um den Browser auf eine neue Seite umzuleiten. Daher ermöglicht die Kontrolle über dieses Objekt, eine offene Redirect-Anfälligkeit auszunutzen.
Der Ausnutzungsprozess ist identisch für die folgenden Szenarien.
window.location.assign()
(unddocument.location.assign()
)
Diese Methode bewirkt, dass das Fenster das Dokument an der angegebenen URL lädt und anzeigt. Wenn wir Kontrolle über diese Methode haben, könnte sie ein Ziel für einen offenen Redirect-Angriff sein.
window.location.replace()
(unddocument.location.replace()
)
Diese Methode ersetzt die aktuelle Ressource durch die an der angegebenen URL.
Der Unterschied zur Methode assign()
besteht darin, dass nach der Verwendung von window.location.replace()
die aktuelle Seite nicht im Sitzungsverlauf gespeichert wird. Es ist jedoch auch möglich, eine offene Redirect-Anfälligkeit auszunutzen, wenn wir Kontrolle über diese Methode haben.
window.open()
Die Methode window.open()
nimmt eine URL und lädt die Ressource, die sie identifiziert, in einen neuen oder bestehenden Tab oder ein neues Fenster. Die Kontrolle über diese Methode könnte ebenfalls eine Gelegenheit sein, eine XSS- oder offene Redirect-Anfälligkeit auszulösen.
Angular-Klassen
Laut Angular-Dokumentation ist Angular
Document
dasselbe wie das DOM-Dokument, was bedeutet, dass es möglich ist, gängige Vektoren für das DOM-Dokument zu verwenden, um clientseitige Anfälligkeiten in Angular auszunutzen. Die Eigenschaften und Methoden vonDocument.location
könnten Ziele für erfolgreiche offene Redirect-Angriffe sein, wie im Beispiel gezeigt:
Während der Forschungsphase haben wir auch die Angular
Location
-Klasse auf offene Redirect-Anfälligkeiten überprüft, aber es wurden keine gültigen Vektoren gefunden.Location
ist ein Angular-Dienst, den Anwendungen verwenden können, um mit der aktuellen URL des Browsers zu interagieren. Dieser Dienst hat mehrere Methoden, um die gegebene URL zu manipulieren -go()
,replaceState()
undprepareExternalUrl()
. Wir können sie jedoch nicht für die Umleitung zu einer externen Domain verwenden. Zum Beispiel:
Ergebnis: http://localhost:4200/http://google.com/about
Die Angular
Router
-Klasse wird hauptsächlich für die Navigation innerhalb derselben Domain verwendet und führt nicht zu zusätzlichen Anfälligkeiten in der Anwendung:
Ergebnis: http://localhost:4200/https:
Die folgenden Methoden navigieren ebenfalls innerhalb des Geltungsbereichs der Domain:
Referenzen
Last updated