Einschleusung - XSS
Cross-Site Scripting, auch als XSS bekannt, ist eine weitere Art von Injektionsschwachstelle, die zur Auswertung eines vom Angreifer kontrollierten Skripts im Browser eines anderen Benutzers führt. XSS kann auch als eine HTML/JavaScript-Injektionsschwachstelle betrachtet werden.
Die Auswirkungen einer XSS-Schwachstelle hängen stark von dem Kontext ab, in dem die Schwachstelle besteht. Sie reichen von der Möglichkeit, Informationen von der Seite zu extrahieren, auf der das Skript ausgeführt wird, bis zur Bearbeitung des Seitenstatus, um als Opfer auf der Seite Aktionen durchzuführen.
Schauen wir uns die Arten von XSS an, die auftreten können.
XSS-Typen
XSS können zur besseren Unterscheidung in mehrere Kategorien eingeteilt werden. Sie werden danach kategorisiert, wie die Nutzlast zugestellt wird und wo sich der Einstiegspunkt befindet.
Übermittlungsvektor der Nutzlast (gespeichert vs. reflektiert)
Es gibt zwei Möglichkeiten, wie ein Angreifer eine XSS-Nutzlast übermitteln kann:
- Gespeicherte XSS: Durch benutzergesteuerte Daten, die z. B. in einer Datenbank gespeichert sind, wo die Daten für andere Benutzer angezeigt werden
- Reflected XSS: Durch eine vom Benutzer bereitgestellte Nutzlast, die über die URL/den Abfrage-String weitergeleitet wird, die/den ein Benutzer aufruft
Der entscheidende Unterschied besteht darin, dass ein Reflected XSS in der Regel von der Interaktion des Benutzers abhängt und sich nur auf den Benutzer auswirkt, der den Link mit der bösartigen Nutzlast öffnet. Ein Stored XSS kann jedoch gegen einen oder mehrere Benutzer ausgeführt werden, indem einfach einige Seiten geöffnet werden, die die Nutzlast darstellen.
Ort der Nutzlast (DOM vs. Nicht-DOM)
Der Ort, an dem eine Nutzlast injiziert wird, bestimmt, ob Sie die Schwachstelle als "DOM"-Schwachstelle einstufen oder nicht. Dies bezieht sich auf die Unterscheidung, wo die Nutzlast gerendert wird:
- Non-DOM XSS: Die Nutzlast wird innerhalb von HTML gerendert, sei es innerhalb eines Tags oder eines Attributs
- DOM XSS: The payload is rendered inside JavaScript, like a `<script>` tag, or an event handler such as `onclick=""`
XSS - Verteidigungsprimitive
In diesem Abschnitt werden die Prinzipien der Primitive betrachtet, die der Verteidigung gegen XSS zugrunde liegen. Es ist wichtig, die Grundlagen zu verstehen, aber in der Praxis sollten Sie sich für 99 % des Schutzes gegen XSS auf Ihre Template-Bibliothek verlassen.
Wenn Sie Vorlagen schreiben, die als Markup oder Code in einem Browser ausgeführt werden, liegt der Schlüssel zum Schutz vor XSS in der *Kodierung*. Kodierung bedeutet in diesem Zusammenhang, dass eine Zeichenfolge in ein Format umgewandelt wird, das vom Interpreter auf eine bestimmte Weise verarbeitet wird.
Die Art der Kodierung hängt jedoch vom Ort oder Kontext ab, in dem die Daten verwendet werden.
- Inside a tag, like `<div>User input here</div>`: **HTML Encoding**
- Inside an attribute, like `<input placeholder="User input here"></input>`: **Attribute Encoding**
- Inside Javascript, like `<script>x = "User input here";</script>`: **JavaScript Encoding**
Einige Frameworks verzichten auf die Verschlüsselung als primäres Verteidigungsmittel und verwenden stattdessen die Bereinigung, um einen Wert aus allen Inhalten zu entfernen, die gefährlich sein könnten. Dies ist ein sehr viel komplexerer Prozess, bei dem viele Grenzfälle zu berücksichtigen sind. Es wird nicht empfohlen, eigene Bereinigungsroutinen zu implementieren.
Beispiele
Schauen wir uns einige Beispiele in verschiedenen Sprachen an, um zu sehen, wie das Ganze in der Praxis aussieht.
C# - Unsicher: Razor
Wenn einem "IHtmlContent"-Objekt ein "@" vorangestellt ist, wird der Wert direkt und ohne Kodierung in die Vorlage eingefügt.
<!--- UNSAFE: The htmlSnippet will get interpreted without any escaping --->
@Html.Raw(htmlSnippet)
C# - Sicher: Razor
Standardmäßig wird jede Zeichenkette, der ein "@" vorangestellt ist, in Razor-Schablonen mit einem HTML-Escap versehen.
<!--- SAFE: The htmlSnippet will get HTML escaped --->
@htmlSnippet
Java - Sicher: JSP
Bei der Verwendung von "c:out" wird standardmäßig XML-Escape verwendet (was mit der Eigenschaft "escapeXml" geändert werden kann), was in einem HTML-Kontext vor XSS schützt, aber nicht in anderen Kontexten.
<div><c:out value="<%= author %>" /></div>
Java - Sicher: (fnxml)
Ähnlich wie oben, können Sie auch direkt `fn:escapeXml` aufrufen, das die Eingabe in XML umwandelt. Auch dies schützt nur in einem HTML-Kontext.
<div>${fn:escapeXml(author)}</div>
Javascript - Unsicher: Angular innerHtml
Durch die Angabe der Eigenschaft `innerHTML` sind Sie, wie der Name schon sagt, aufgrund der Deaktivierung der Ausgabekodierung dem Risiko von XSS ausgesetzt.
<!--- UNSAFE: The htmlSnippet will get interpreted without any encoding --->
<p [innerHTML]="htmlSnippet"></p>
Javascript - Sicher: Angular interpoliert
Angulars Interpolation von Text unter Verwendung von doppelten geschweiften Klammern (`{{` und `}}`) bietet HTML-Escape für die Ausgabe und schützt so vor XSS.
<!--- SAFE: The htmlSnippet will get encoded and then interpreted --->
<p>{{htmlSnippet}}</p>
Javascript - Unsicher: React dangerousInnerHtml
Durch die Angabe der Eigenschaft `dangerouslySetInnerHTML` sind Sie, wie der Name schon sagt, aufgrund der Deaktivierung der Ausgabekodierung dem Risiko von XSS ausgesetzt.
<!--- UNSAFE: As the name suggests, the dangerouslySetInnerHTML attribute is dangerous as it does not escape the output --->
<div dangerouslySetInnerHTML={{ __html: htmlSnippet }} />;
Javascript - Sicher: React interpoliert
Reacts Interpolation von Text mit geschweiften Klammern (`{` und `}`) wird die Ausgabe mit HTML-Escape versehen und schützt so vor XSS.
<!--- SAFE: The htmlSnippet will get encoded and then interpreted --->
<div>{htmlSnippet}</div>
Python - Unsicher: Django
Wenn man den `safe`-Filter in einem Django-Template verwendet, deaktiviert er das automatische Escaping der Ausgabe und schützt somit nicht vor XSS.
<!--- UNSAFE: The htmlSnippet will not get HTML encoded --->
<div>{{ htmlSnippet | safe }}</div>
Python - Sicher: Django
Djangos Interpolation von Text unter Verwendung von doppelten geschweiften Klammern (`{{` und `}}`) wird die Ausgabe mit HTML-Escape versehen und schützt so vor XSS.
<!--- SAFE: The htmlSnippet will HTML encoded --->
<div>{{ name }}</div>