Heim >Web-Frontend >js-Tutorial >Ihr Rich Text könnte eine Cross-Site-Scripting-Schwachstelle sein

Ihr Rich Text könnte eine Cross-Site-Scripting-Schwachstelle sein

DDD
DDDOriginal
2024-12-30 19:15:10939Durchsuche

SXSS-Schwachstellen erkennen und beheben, bevor sie ausgenutzt werden

Von Luke Harrison

Dieser Artikel wurde ursprünglich auf IBM Developer veröffentlicht.

Viele aktuelle Anwendungen müssen Rich Text in HTML auf ihren Websites rendern. Um diesen formatierten Text aus Benutzereingaben zu generieren, verwenden Entwickler eine Rich-Text-Editor-Komponente. Das Problem? Diese Funktionalität kann indirekt sowohl Ihre Anwendung als auch Ihre Daten einer Schwachstelle aussetzen, die als gespeichertes Cross-Site-Scripting (SXSS) bezeichnet wird.

In diesem Artikel erfahren Sie, was eine SXSS-Schwachstelle ist und sehen sich einige „Code Smells“ an, mit denen Sie überprüfen können, ob Ihre Anwendungen betroffen sind. Außerdem sehen Sie ein Beispiel einer anfälligen Anwendung und lernen eine Behebungsstrategie für diese Schwachstelle kennen.

Was ist gespeichertes Cross-Site-Scripting?

Gespeichertes Cross-Site-Scripting ist eine Art von Schwachstelle, die Angreifer ausnutzen können, um Schadcode in eine Datenbank einzuschleusen. Dieser Code wird dann im Browser des Opfers ausgeführt, nachdem er von einem Front-End-Framework abgerufen und gerendert wurde.

Diese Sicherheitslücke ist äußerst gefährlich, da sie es Angreifern ermöglichen kann, Cookies zu stehlen, Weiterleitungen auszulösen oder eine Reihe gefährlicher Skripte im Browser des Opfers auszuführen. Für die Verbreitung des Exploits ist seitens des Angreifers nur sehr wenig Arbeit erforderlich: Das Opfer muss nicht auf einen bösartigen Link klicken oder auf einen Phishing-Angriff hereinfallen, sondern nutzt lediglich eine vertrauenswürdige Website, die von SXSS betroffen ist. Weitere Informationen zu Cross-Site-Scripting-Schwachstellen finden Sie unter den Links unten auf der Seite.

Codegeruch: innerHTML und gefährlichSetInnerHTML

Ein Code-Geruch ist einfach ein Merkmal im Code, das auf ein tiefer liegendes Problem hinweist. Normalerweise führen Browser injizierte Skripte nicht automatisch aus, aber wenn ein Entwickler potenziell gefährliche Browser-APIs oder Elementeigenschaften verwendet, kann es dazu kommen, dass die Skripte nicht ausgeführt werden.

Sehen Sie sich den folgenden Codeausschnitt an:

const someHTML = “<h1>Hello world</h1>“

const output = document.getElementById("rich-text-output");

output.innerHTML = someHTML

In diesem Beispiel speichern wir etwas HTML in einer Variablen, rufen ein Element aus dem DOM ab und setzen die innerHTML-Eigenschaft dieses Elements auf den in der Variablen gespeicherten Inhalt. Die innerHTML-Eigenschaft kann verwendet werden, um HTML aus einer Zeichenfolge innerhalb eines anderen HTML-Elements zu rendern.

Das Gefährliche an dieser Eigenschaft ist, dass sie jegliches HTML oder JavaScript rendert, das Sie ihr übergeben. Das heißt, wenn jemand in der Lage wäre, die Daten zu kontrollieren, die an die Immobilie übergeben werden, könnte er technisch gesehen jedes JavaScript im Browser eines Benutzers ausführen.

Eine weitere beliebte, aber gefährliche Möglichkeit, dynamisches HTML in einem Browser darzustellen, ist die Verwendung der React-Komponenteneigenschaft „dangerouslySetInnerHTML“. Diese Eigenschaft verhält sich genauso wie die innerHTML-Eigenschaft in Vanilla-JavaScript und HTML.

Das folgende Beispiel erscheint in den React-Dokumenten:

const someHTML = “<h1>Hello world</h1>“

const output = document.getElementById("rich-text-output");

output.innerHTML = someHTML

Wenn Sie derzeit eine dieser Eigenschaften in einer Front-End-Webanwendung verwenden, besteht eine gute Chance, dass Sie eine Art Cross-Site-Scripting-Schwachstelle haben. Wir werden uns später in diesem Artikel ansehen, wie diese Eigenschaften ausgenutzt werden können, und einige Schritte, die Sie unternehmen können, um diese Probleme zu beheben.

Codegeruch: Rich-Text-Editoren

Ein weiteres Anzeichen dafür, dass Ihre Anwendung möglicherweise anfällig für SXSS ist, ist einfach, ob Sie einen Rich-Text-Editor wie TinyMCE oder CKEditor verwenden oder nicht.

Your rich text could be a cross-site scripting vulnerability

Your rich text could be a cross-site scripting vulnerability

Die meisten Rich-Text-Editoren funktionieren, indem sie von einem Benutzer generierten formatierten Text in HTML konvertieren. Als zusätzliche Sicherheitsmaßnahme verwenden viele dieser Editoren eine Form der Bereinigung, um potenziell schädliches JavaScript aus ihren Eingaben zu entfernen. Wenn Sie jedoch nicht dieselben Bereinigungstechniken auf die Dienste anwenden, die den Rich-Text-Inhalt empfangen und speichern, machen Sie Ihre Anwendungen wahrscheinlich für SXSS anfällig.

Selbst wenn Sie den Inhalt nicht auf Ihren eigenen Websites rendern, besteht eine gute Chance, dass diese Daten von Anwendungen verbraucht werden, die die Inhalte rendern. Beim Entwerfen sicherer Anwendungen ist es äußerst wichtig, dass Sie die aktuellen und zukünftigen Verbraucher Ihrer Daten berücksichtigen. Wenn Ihre Daten von SXSS betroffen sind, gilt dies auch für alle Anwendungen, die Ihre Daten verbrauchen.

Beispielanwendung mit SXSS-Schwachstelle

Sehen wir uns ein kleines Beispiel einer Webanwendung mit einer SXSS-Schwachstelle an und versuchen wir dann, diese auszunutzen.

Um diese Anwendung auszuführen, klonen Sie zunächst dieses Demo-App-Repository und befolgen Sie die Anweisungen zum „Ausführen der Anwendung“ in der Datei readme.md.

Nachdem Sie die Anwendung ausgeführt und zu http://localhost:3000/unsanitized.html gegangen sind, sollten Sie eine Seite sehen, die so aussieht:

Your rich text could be a cross-site scripting vulnerability

Diese Anwendung nimmt einfach einige Rich-Text-Eingaben von einem Benutzer entgegen, speichert sie auf einem Webserver und rendert sie dann im Abschnitt mit der Bezeichnung Ausgabe.

Bevor wir die SXSS-Schwachstelle ausnutzen, nehmen Sie sich einen Moment Zeit, um einen Blick auf die Anwendung zu werfen. Sehen Sie sich die oben genannten Code-Smells an und scannen Sie den Code, um zu sehen, ob Sie die problematischen Abschnitte erkennen können. Versuchen Sie, die Registerkarte „Netzwerk“ in Ihrem Browser zu öffnen und sehen Sie sich die Anfragen an, die gesendet werden, wenn Sie Rich-Text eingeben und übermitteln.

In der Datei unsanitzed.html sehen Sie die folgende Funktion mit dem Namen renderPostByID:

const someHTML = “<h1>Hello world</h1>“

const output = document.getElementById("rich-text-output");

output.innerHTML = someHTML

Schauen Sie sich diese Funktion genau an. Sie werden feststellen, dass wir die oben erwähnte innerHTML-Eigenschaft verwenden, um Rich-Text, den wir von der API abgerufen haben, in HTML-Form darzustellen.

Da wir nun den anfälligen Teil des Codes sehen, wollen wir ihn ausnutzen. Wir umgehen die Rich-Text-Editor-Eingabe und greifen auf den API-Endpunkt zu, der Beiträge direkt auf dem Webserver speichert. Dazu können Sie den folgenden cURL-Befehl verwenden:

function createMarkup() {

  return {__html: 'First &middot; Second'};

}

function MyComponent() {

  return <div dangerouslySetInnerHTML={createMarkup()} />;

}

Beachten Sie die Datennutzlast, die wir in der Anfrage senden. Hierbei handelt es sich um in böser Absicht erstelltes HTML, das ein Bild-Tag mit einer auf JavaScript gesetzten onerror-Eigenschaft enthält, die einen Warndialog anzeigt. Angreifer nutzen solche Tricks, um schlecht implementierte Sanierungsmethoden zu umgehen, die darauf abzielen, JavaScript aus HTML-Elementen zu entfernen, bevor diese in einer Datenbank gespeichert werden.

Nachdem Sie das obige Skript ausgeführt haben, sollten Sie eine Beitrags-ID wie die folgende erhalten:

const renderPostByID = async (id) => {
    // setting url seach params
    let newURL = window.location.protocol + "//" + window.location.host + window.location.pathname + `?post=${id}`;
    window.history.pushState({ path: newURL }, "", newURL);

    // getting rich text by post id
    let response = await fetch(`/unsanitized/${id}`, { method: "GET" });
    let responseJSON = await response.json();
    console.log(responseJSON);

    // rendering rich text
    output.innerHTML = responseJSON.richText;
};

Fügen Sie diese Beitrags-ID in den Abfrageparameter der Beitrags-URL ein und drücken Sie die Eingabetaste.

Your rich text could be a cross-site scripting vulnerability

Wenn Sie dies tun, sollte auf Ihrem Bildschirm ein Warndialog angezeigt werden, der bestätigt, dass die Website tatsächlich für SXSS anfällig ist.

Your rich text could be a cross-site scripting vulnerability

So verhindern Sie SXSS

Da wir nun gesehen haben, wie man eine SXSS-Schwachstelle ausnutzt, werfen wir einen Blick darauf, wie wir eine beheben können. Dazu müssen Sie den HTML-basierten Rich-Text an drei verschiedenen Stellen bereinigen:

  1. Serverseitig, bevor der Inhalt in Ihrer Datenbank gespeichert wird.
  2. Serverseitig, wenn der Inhalt aus Ihrer Datenbank abgerufen wird.
  3. Clientseitig, wenn der Inhalt vom Browser gerendert wird.

Es mag klar sein, warum Sie den Inhalt bereinigen möchten, bevor Sie ihn in der Datenbank speichern und wenn Sie ihn auf der Clientseite rendern, aber warum sollten Sie ihn bereinigen, wenn Sie ihn abrufen? Stellen wir uns vor, jemand erhält die erforderlichen Berechtigungen, um Inhalte direkt in Ihre Datenbank einzufügen. Sie konnten nun direkt böswillig erstellten HTML-Code einfügen und dabei den anfänglichen Sanitizer vollständig umgehen. Wenn ein Verbraucher einer Ihrer APIs diese Bereinigung nicht auch auf der Clientseite implementiert, könnte er Opfer des Cross-Site-Scripting-Exploits werden.

Bedenken Sie jedoch, dass die zusätzliche Desinfektion aller drei Standorte zu Leistungseinbußen führen kann. Sie müssen daher selbst entscheiden, ob Sie dieses Sicherheitsniveau benötigen. Zumindest sollten Sie alle Daten auf der Clientseite bereinigen, bevor Sie dynamische HTML-Inhalte rendern.

Sehen wir uns an, wie wir die Bereinigung in der sicheren Version unserer anfälligen Anwendung implementieren. Da diese Anwendung hauptsächlich mit JavaScript geschrieben wird, verwenden wir die dompurify-Bibliothek für die Clientseite und die isomorphic-dompurify-Bibliothek für die serverseitige Bereinigung. Im app.js-Programm, das als unser Webserver fungiert, finden Sie einen Express-Endpunkt /sanitized mit einer GET- und POST-Implementierung:

const someHTML = “<h1>Hello world</h1>“

const output = document.getElementById("rich-text-output");

output.innerHTML = someHTML

In der POST-Implementierung rufen wir zunächst den Rich-Text aus dem Hauptteil der Anfrage ab und rufen dann die Sanitize-Methode der isomorphic-dompurify-Bibliothek auf, bevor wir ihn in unserem Datenobjekt speichern. In ähnlicher Weise rufen wir in der GET-Implementierung dieselbe Methode für den Rich-Text auf, nachdem wir ihn aus unserem Datenobjekt abgerufen und bevor wir ihn an unseren Verbraucher senden.

Auf der Clientseite verwenden wir erneut dieselbe Methode, bevor wir die innerHTML-Eigenschaft unseres Ausgabe-Div in sanitized.html festlegen.

function createMarkup() {

  return {__html: 'First &middot; Second'};

}

function MyComponent() {

  return <div dangerouslySetInnerHTML={createMarkup()} />;

}

Da Sie nun gesehen haben, wie wir HTML ordnungsgemäß bereinigen, um Cross-Site-Scripting zu verhindern, kehren Sie zum ursprünglichen Exploit für diese Anwendung zurück und führen Sie ihn erneut aus, dieses Mal mit dem bereinigten Endpunkt. Das Warndialog-Popup sollte nicht mehr angezeigt werden, da wir jetzt die richtigen Techniken verwenden, um die SXSS-Schwachstelle zu verhindern.

Eine vollständige SXSS-Anleitung, einschließlich Best Practices und anderer Techniken zur Verhinderung von XSS, finden Sie im OWASP Cross-Site Scripting Spickzettel.

Zusammenfassung und nächste Schritte

In diesem Artikel haben wir untersucht, wie Sie den Sicherheitsstatus Ihrer Anwendung verbessern können, indem Sie gespeichertes Cross-Site-Scripting verhindern, eine häufige Art von Schwachstelle in Webanwendungen. Sie sollten nun in der Lage sein, zu erkennen, ob Ihre eigenen Anwendungen anfällig sind, welche Funktionen Sie überprüfen müssen und wie Sie Abhilfemaßnahmen ergreifen können, bevor böswillige Akteure diese Schwachstellen ausnutzen können.

Sicherheit ist für Unternehmensentwickler von größter Bedeutung. Nutzen Sie die folgenden Ressourcen, um Ihr Bewusstsein für mögliche Schwachstellen und die Möglichkeiten, wie Sie Ihre Sicherheitslage verbessern können, weiter zu stärken.

  • IBM Developer: Sicherheitshub
  • OWASP Cross Site Scripting-Übersicht
  • Video: Cross-Site Scripting – eine seit 25 Jahren bestehende Bedrohung, die immer noch anhält

Das obige ist der detaillierte Inhalt vonIhr Rich Text könnte eine Cross-Site-Scripting-Schwachstelle sein. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn