NodeJS - __proto__ & prototype Pollution
Objekte in JavaScript
Objekte in JavaScript sind im Wesentlichen Sammlungen von Schlüssel-Wert-Paaren, die als Eigenschaften bekannt sind. Ein Objekt kann mit Object.create
und null
als Argument erstellt werden, um ein leeres Objekt zu erzeugen. Diese Methode ermöglicht die Erstellung eines Objekts ohne vererbte Eigenschaften.
Ein leeres Objekt entspricht einem leeren Wörterbuch, dargestellt als {}
.
Funktionen und Klassen in JavaScript
In JavaScript sind Klassen und Funktionen eng miteinander verbunden, wobei Funktionen oft als Konstruktoren für Klassen dienen. Trotz des Mangels an nativer Klassenunterstützung in JavaScript können Konstruktoren das Verhalten von Klassen nachahmen.
Prototypen in JavaScript
JavaScript ermöglicht die Modifikation, Hinzufügung oder Löschung von Prototyp-Attributen zur Laufzeit. Diese Flexibilität ermöglicht die dynamische Erweiterung von Klassenfunktionalitäten.
Funktionen wie toString
und valueOf
können verändert werden, um ihr Verhalten zu ändern und damit die anpassungsfähige Natur des JavaScript-Prototypsystems zu demonstrieren.
Vererbung
Im prototypenbasierten Programmieren werden Eigenschaften/Methoden von Klassen von Objekten geerbt. Diese Klassen werden erstellt, indem Eigenschaften/Methoden entweder zu einer Instanz einer anderen Klasse oder zu einem leeren Objekt hinzugefügt werden.
Es sollte beachtet werden, dass wenn einer Instanz, die als Prototyp für andere Objekte dient (wie myPersonObj
), eine Eigenschaft hinzugefügt wird, die ererbenden Objekte Zugriff auf diese neue Eigenschaft erhalten. Diese Eigenschaft wird jedoch nicht automatisch angezeigt, es sei denn, sie wird explizit aufgerufen.
__proto__ Pollution
Erkundung der Prototypenverschmutzung in JavaScript
JavaScript-Objekte werden durch Schlüssel-Wert-Paare definiert und erben vom JavaScript-Objekt-Prototyp. Dies bedeutet, dass die Änderung des Objekt-Prototyps alle Objekte in der Umgebung beeinflussen kann.
Lassen Sie uns ein anderes Beispiel verwenden, um dies zu veranschaulichen:
Zugriff auf das Objekt-Prototyp ist möglich durch:
Durch das Hinzufügen von Eigenschaften zum Object-Prototyp erbt jedes JavaScript-Objekt diese neuen Eigenschaften:
Prototyp-Verschmutzung
Für ein Szenario, in dem die Verwendung von __proto__
eingeschränkt ist, ist die Modifizierung des Prototyps einer Funktion eine Alternative:
Dies betrifft nur Objekte, die aus dem Vehicle
-Konstruktor erstellt wurden, und verleiht ihnen die Eigenschaften beep
, hasWheels
, honk
und isElectric
.
Zwei Methoden, um JavaScript-Objekte global durch Prototypen-Verschmutzung zu beeinflussen, sind:
Direktes Verschmutzen des
Object.prototype
:
Verschmutzen des Prototyps eines Konstruktors für eine häufig verwendete Struktur:
Nach diesen Operationen kann jedes JavaScript-Objekt goodbye
und greet
Methoden ausführen.
Verunreinigung anderer Objekte
Von einer Klasse zu Object.prototype
In einem Szenario, in dem Sie ein bestimmtes Objekt verunreinigen können und zu Object.prototype
gelangen müssen, können Sie danach mit einem Code wie dem folgenden suchen:
Array-Elementverschmutzung
Beachten Sie, dass Sie, wie Sie Attribute von Objekten in JS verschmutzen können, wenn Sie Zugriff haben, um ein Array zu verschmutzen, auch Werte des Arrays verschmutzen können, die über Indizes zugänglich sind (beachten Sie, dass Sie Werte nicht überschreiben können, daher müssen Sie Indizes verschmutzen, die auf irgendeine Weise verwendet, aber nicht geschrieben werden).
Html-Elemente-Verschmutzung
Beim Generieren eines HTML-Elements über JS ist es möglich, das innerHTML
-Attribut zu überschreiben, um es dazu zu bringen, beliebigen HTML-Code zu schreiben. Idee und Beispiel aus diesem Bericht.
Beispiele
Grundlegendes Beispiel
Eine Prototyp-Verunreinigung tritt aufgrund eines Fehlers in der Anwendung auf, der das Überschreiben von Eigenschaften auf Object.prototype
ermöglicht. Dies bedeutet, dass da die meisten Objekte ihre Eigenschaften von Object.prototype
ableiten.
Das einfachste Beispiel besteht darin, einen Wert zu einem undefinierten Attribut eines Objekts hinzuzufügen, das überprüft werden soll, wie:
Wenn das Attribut admin
undefiniert ist, ist es möglich, eine PP auszunutzen und es auf True zu setzen, beispielsweise mit:
Der Mechanismus dahinter beinhaltet die Manipulation von Eigenschaften, so dass ein Angreifer bei Kontrolle über bestimmte Eingaben das Prototyp aller Objekte in der Anwendung ändern kann. Diese Manipulation beinhaltet typischerweise das Setzen der __proto__
Eigenschaft, die in JavaScript gleichbedeutend mit der direkten Modifikation des Prototyps eines Objekts ist.
Die Bedingungen, unter denen dieser Angriff erfolgreich ausgeführt werden kann, wie in einer spezifischen Studie dargelegt, umfassen:
Durchführung einer rekursiven Zusammenführung.
Definition von Eigenschaften basierend auf einem Pfad.
Klonen von Objekten.
Funktion überschreiben
Proto Pollution zu RCE
pagePrototype Pollution to RCEAndere Payloads:
Client-seitige Prototype Pollution zu XSS
pageClient Side Prototype PollutionCVE-2019–11358: Prototype Pollution Angriff durch jQuery $ .extend
Für weitere Details siehe diesen Artikel In jQuery kann die $ .extend
Funktion zu Prototype Pollution führen, wenn das Deep-Copy-Feature falsch verwendet wird. Diese Funktion wird häufig zum Klonen von Objekten oder zum Zusammenführen von Eigenschaften aus einem Standardobjekt verwendet. Wenn sie jedoch falsch konfiguriert ist, können Eigenschaften, die für ein neues Objekt vorgesehen sind, stattdessen dem Prototyp zugewiesen werden. Zum Beispiel:
Diese Schwachstelle, identifiziert als CVE-2019–11358, veranschaulicht, wie eine Deep Copy versehentlich das Prototype ändern kann, was zu potenziellen Sicherheitsrisiken führt, wie z. B. unbefugtem Admin-Zugriff, wenn Eigenschaften wie isAdmin
ohne ordnungsgemäße Existenzüberprüfung überprüft werden.
CVE-2018–3721, CVE-2019–10744: Prototype-Pollution-Angriff über lodash
Weitere Details finden Sie in diesem Artikel
Lodash stieß auf ähnliche Prototype-Pollution-Schwachstellen (CVE-2018–3721, CVE-2019–10744). Diese Probleme wurden in Version 4.17.11 behoben.
Ein weiteres Tutorial mit CVEs
Tools zur Erkennung von Prototype Pollution
Server-Side-Prototype-Pollution-Gadgets-Scanner: Eine Burp Suite-Erweiterung, die entwickelt wurde, um serverseitige Prototype-Pollution-Schwachstellen in Webanwendungen zu erkennen und zu analysieren. Dieses Tool automatisiert den Prozess des Scannens von Anfragen, um potenzielle Prototype-Pollution-Probleme zu identifizieren. Es nutzt bekannte Gadgets - Methoden zur Ausnutzung von Prototype-Pollution, um schädliche Aktionen auszuführen - und konzentriert sich insbesondere auf Node.js-Bibliotheken.
server-side-prototype-pollution: Diese Erweiterung identifiziert serverseitige Prototype-Pollution-Schwachstellen. Sie verwendet Techniken, die in der Serverseitige Prototype Pollution beschrieben sind.
AST Prototype Pollution in NodeJS
NodeJS nutzt Abstract Syntax Trees (AST) in JavaScript umfangreich für Funktionen wie Template-Engines und TypeScript. Dieser Abschnitt untersucht die mit der Prototype-Pollution in Template-Engines, insbesondere Handlebars und Pug, verbundenen Schwachstellen.
Analyse der Handlebars-Schwachstelle
Die Handlebars-Template-Engine ist anfällig für einen Prototype-Pollution-Angriff. Diese Schwachstelle ergibt sich aus spezifischen Funktionen innerhalb der Datei javascript-compiler.js
. Die Funktion appendContent
beispielsweise konkateniert pendingContent
, wenn es vorhanden ist, während die Funktion pushSource
nach dem Hinzufügen der Quelle pendingContent
auf undefined
zurücksetzt.
Ausbeutungsprozess
Die Ausbeutung nutzt den von Handlebars erstellten AST (Abstract Syntax Tree) und folgt diesen Schritten:
Manipulation des Parsers: Zunächst erzwingt der Parser über den
NumberLiteral
-Knoten, dass Werte numerisch sind. Die Prototype-Pollution kann dies umgehen und das Einfügen von nicht-numerischen Zeichenfolgen ermöglichen.Behandlung durch den Compiler: Der Compiler kann ein AST-Objekt oder eine Zeichenfolgevorlage verarbeiten. Wenn
input.type
gleichProgram
ist, wird die Eingabe als voranalysiert behandelt, was ausgenutzt werden kann.Einschleusen von Code: Durch Manipulation von
Object.prototype
kann beliebiger Code in die Vorlagenfunktion eingeschleust werden, was zu einer Remote-Code-Ausführung führen kann.
Ein Beispiel, das die Ausnutzung der Handlebars-Schwachstelle demonstriert:
Dieser Code zeigt, wie ein Angreifer beliebigen Code in eine Handlebars-Vorlage einschleusen könnte.
Externe Referenz: Ein Problem im Zusammenhang mit der Prototyp-Verunreinigung wurde in der 'flat'-Bibliothek gefunden, wie hier detailliert beschrieben: Problem auf GitHub.
Externe Referenz: Problem im Zusammenhang mit der Prototyp-Verunreinigung in der 'flat'-Bibliothek
Beispiel für einen Prototyp-Verunreinigungsangriff in Python:
Pug-Schwachstelle
Pug, eine weitere Template-Engine, ist einem ähnlichen Risiko der Prototyp-Verunreinigung ausgesetzt. Detaillierte Informationen finden Sie in der Diskussion über AST-Injektion in Pug.
Beispiel für Prototyp-Verunreinigung in Pug:
Vorbeugende Maßnahmen
Um das Risiko einer Prototyp-Verschmutzung zu reduzieren, können die unten aufgeführten Strategien angewendet werden:
Objekt-Unveränderlichkeit: Das
Object.prototype
kann durch Anwendung vonObject.freeze
unveränderlich gemacht werden.Eingabevalidierung: JSON-Eingaben sollten rigoros gegen das Anwendungsschema validiert werden.
Sichere Merge-Funktionen: Der unsichere Einsatz von rekursiven Merge-Funktionen sollte vermieden werden.
Prototyplose Objekte: Objekte ohne Prototyp-Eigenschaften können mit
Object.create(null)
erstellt werden.Verwendung von Map: Anstelle von
Object
sollteMap
zur Speicherung von Schlüssel-Wert-Paaren verwendet werden.Bibliotheksaktualisierungen: Sicherheitspatches können durch regelmäßige Aktualisierungen von Bibliotheken eingebunden werden.
Linter und statische Analysetools: Verwenden Sie Tools wie ESLint mit geeigneten Plugins, um Prototyp-Verschmutzungsanfälligkeiten zu erkennen und zu verhindern.
Code-Reviews: Implementieren Sie gründliche Code-Reviews, um potenzielle Risiken im Zusammenhang mit Prototyp-Verschmutzung zu identifizieren und zu beheben.
Sicherheitstraining: Schulen Sie Entwickler über die Risiken der Prototyp-Verschmutzung und bewährte Verfahren für das Schreiben von sicherem Code.
Verwendung von Bibliotheken mit Vorsicht: Seien Sie vorsichtig bei der Verwendung von Drittanbieter-Bibliotheken. Bewerten Sie ihre Sicherheitslage und überprüfen Sie ihren Code, insbesondere bei der Manipulation von Objekten.
Laufzeitschutz: Verwenden Sie Laufzeitschutzmechanismen wie die Verwendung von auf Sicherheit ausgerichteten npm-Paketen, die Prototyp-Verschmutzungsangriffe erkennen und verhindern können.
Referenzen
Last updated