Prompt Injection
Andrea Hauser
So funktioniert Prototype Pollution
Dieser Abschnitt beschreibt JavaScript-Grundlagen, wenn Sie sich mit JavaScript bereits auskennen, können Sie diesen Abschnitt problemlos überspringen.
Ein Objekt ist eigentlich nur eine Ansammlung von Properties, wobei Properties key:value
Paare sind. Ein Objekt sieht wie folgt aus:
var exampleObject = { test: "value", exampelMethod: function() { //do something here console.log("test") } }
Auf die Properties eines Objekts können wie folgt zugegriffen werden:
exampleObject.test
oder
exampleObject['test']
und die Methode eines Objekts kann wie folgt aufgerufen werden:
exampleObject.exampleMethod();
Beim Beispiel oben handelt es sich um ein explizit deklariertes Objekt, in JavaScript basiert allerdings fast alles im Hintergrund auf Objekten. Gelöst wird das ganze über den Prototype.
Beim Prototype handelt es sich um den Mechanismus, mit dem in JavaScript Elemente von Objekten an andere Objekte vererbt werden. Der Prototyp eines Objekts ist nichts anderes als ein weiteres Objekt, das ebenfalls einen eigenen Prototyp hat. Und da praktisch alles in JavaScript unter der Oberfläche ein Objekt ist, führt diese Kette letztlich zum obersten Object.prototype
zurück, dessen Prototyp dann einfach der Wert null
ist.
In der Praxis bedeutet das, dass JavaScript im Hintergrund folgendes macht, wenn auf ein Property mittels exampleObject.test
oder exampleObject['test']
zugegriffen wird:
test
in dem Objekt exampleObject
.undefined
zurückgegeben.Auf einem Objekt kann wie folgt auf den Prototype zugegriffen werden:
__proto__
constructor.prototype
Mit diesen Grundlagen sollten Sie nun in der Lage sein, JavaScript Prototype Pollution zu verstehen.
Bei einer Prototype Pollution hat ein Angreifer das Ziel Object.prototype
zu verändern. Da beinahe alle Elemente in JavaScript von Objekt erben, können damit beinahe alle Elemente angegriffen werden. In den meisten Fällen wird Prototype Pollution durch eine unsicher merge Funktion ausgelöst, die rekursiv Properties aus einer nicht vertrauenswürdigen Quelle übernimmt. Olivier Arteau beschreibt eine solche merge Funktion in seinem Paper Prototype pollution attack in NodeJS application wie folgt:
merge(target, source) foreach property of source if property exists and is an object on both the target and the source merge(target[property], source[property]) else target[property] = source[property]
Für Prototype Pollution wird folgendes benötigt:
Beim DOM Invader handelt es sich um eine Erweiterung des im Burp mitgelieferten Chromium Browsers. Diese Erweiterung ist im Normalfall deaktiviert, da sie ungewünschte Nebenwirkungen haben kann. Sie kann wie folgt aktiviert werden:
Im Burp mitgelieferten Browser die Erweiterung mit dem Titel Burp Suite auswählen:
Und in dem sich öffnenden Fenster DOM Invader auswählen und aktivieren:
Sobald die Erweiterung aktiv ist, kann die Webseite, die auf Prototype Pollution untersucht werden soll, neu geladen werden. Damit wird der DOM Invader im Hintergrund richtig aufgesetzt. In den Developer Tools gibt es nun einen neuen Eintrag mit dem Titel DOM Invader. Wenn dieser Ausgewählt wird, werden die Resultate der Analyse des DOM Invaders angezeigt. Im untenstehenden Beispiel wurden zwei Prototype Pollution Möglichkeiten identifiziert:
Mittels Scan for gadgets
kann nach Gadgets gesucht werden, die aus Prototype Pollution XSS machen. Dabei sieht das Scanning wie folgt aus:
Und das Resultat eines erfolgreichen Scans wie folgt:
Im einfachsten Fall kann einfach die Option Exploit
ausgewählt werden und es wird ein alert(1)
ausgeführt. Falls kein alert auftaucht sollte in der Konsole die Fehlermeldung anzeigt werden und mittels dem dort vorhandenen StackTrace landet man im JavaScript an dem Ort, an dem die Prototype Pollution schiefläuft. Von da kann man dann einfach die Payload analysieren und wie erwartet anpassen, so dass der alert ausgeführt wird.
Die manuelle Suche nach JavaScript Prototype Pollution kann sehr aufwendig sein, vor allem dann, wenn der von der Webseite genutzte JavaScript Code minified wurde. Wie dafür vorgegangen werden kann, wurde in den Artikeln von Portswigger und Nikita Stupin besser und tiefergehend eingegangen, als dass es hier gemacht werden kann. Die Lektüre dieser Artikel ist sehr empfehlenswert, um das Wissen zu Prototype Pollution zu vertiefen. Insbesondere der Portswigger-Artikel ist empfehlenswert, da dort auch Labs angeboten werden, bei denen die gelernten Techniken direkt angewendet werden können.
Es gibt unterschiedliche Möglichkeiten, wie man sich gegen JavaScript Prototype Pollution schützen kann. Diese kommen jeweils mit unterschiedlichen Vor- und Nachteilen:
Object.create(null)
erstellentoString()
nicht mehr verwendet werden können, da diese Standardfunktionen über das Object Prototype an benutzerdefinierte Objekte vererbt werden.__proto__
Object.freeze()
verwendenObject.seal()
verwendet werden, dann können keine neuen Properties mehr definiert werden, aber bestehende Properties können noch verändert werden.Bei JavaScript Prototype Pollution handelt es sich um eine komplexe Angriffsmöglichkeit, die in den schlimmsten Fällen zu XSS oder server-seitig sogar zu RCE führen können. Das Auffinden solcher Schwachstellen ist zwar manuell möglich, ist allerdings sehr aufwändig, da die meisten modernen Webseiten viel und meist minified JavaScript Code haben. Da Portswigger, die Hersteller von Burp, sich ausgiebig mit dem Thema beschäftigt haben, wird innerhalb von Burp allerdings gutes Tooling zur Identifizierung dieses Schwachstellen-Typs zur Verfügung gestellt. Für Entwickler bestehen unterschiedlichste Möglichkeiten mit verschiedenen Vor- und Nachteilen, um JavaScript-Code gegen Prototype Pollution zu härten.
Unsere Spezialisten kontaktieren Sie gern!
Andrea Hauser
Andrea Hauser
Andrea Hauser
Andrea Hauser
Unsere Spezialisten kontaktieren Sie gern!