AI Hacking - Wie Hacker künstliche Intelligenz bei Cyberangriffen einsetzen

Jetzt lesen
Wir verwenden künstliche Intelligenz für Website-Übersetzungen, und obwohl wir uns um Genauigkeit bemühen, kann es sein, dass sie nicht immer 100%ig präzise sind. Wir danken Ihnen für Ihr Verständnis.

Technische Entdeckung von Mongoose CVE-2025-23061 und CVE-2024-53900

von OPSWAT
Jetzt teilen

Mongoose ist eine Object Data Modeling (ODM)-Bibliothek für MongoDB, die die Datenbankinteraktion in Node.js-Anwendungen vereinfacht. Durch die Bereitstellung einer schema-basierten Lösung ermöglicht Mongoose die Abbildung von JavaScript-Objekten auf MongoDB-Dokumente und fungiert als Abstraktionsschicht, die bei der Strukturierung von Daten zur einfacheren Verwaltung und Validierung hilft. Mit Funktionen wie Middleware für die Ausführung benutzerdefinierter Logik und einem intuitiven System zur Erstellung von Abfragen steigert Mongoose die Effizienz der Arbeit mit MongoDB. Mongoose, das als "elegante MongoDB-Objektmodellierung für Node.js" beschrieben wird, hat auf GitHub 27.000 Sterne erhalten, was seine weitverbreitete Nutzung und Wertschätzung unter Entwicklern widerspiegelt.

OPSWAT und Entdeckung kritischer Schwachstellen

Das OPSWAT Critical Infrastructure Cybersecurity Graduate Fellowship Program, das in Vietnam angesiedelt ist, bietet Studenten mit Hochschulabschluss praktische Erfahrungen bei der Sicherung kritischer Infrastrukturen. Im Rahmen dieses Programms haben die Stipendiaten die Möglichkeit, Schwachstellen in der Cybersicherheit zu analysieren und zu beheben und mit OPSWAT zusammenzuarbeiten, um reale Herausforderungen in Bereichen wie Malware-Erkennung, Dateisicherheit und Bedrohungsabwehr zu bewältigen. 

Während des OPSWAT untersuchen und reproduzieren die Teilnehmer systematisch bekannte CVEs in verschiedenen Produkten, Bibliotheken und Betriebssystemen. Im Rahmen dieser Initiative entschied sich Dat Phung - einer unserer angesehenen Stipendiaten - dafür, Mongoose zu untersuchen, da es in Produktionsumgebungen weit verbreitet ist. Im November 2024 entdeckte er eine kritische Schwachstelle in Mongoose, als er eine eingehende Analyse der Bibliothek durchführte. Die Schwachstelle ermöglichte es einem Angreifer, den Wert $where auszunutzen, was zu Remote Code Execution (RCE) auf dem Node.js-Anwendungsserver führen kann. Nachdem das Problem umgehend an Mongoose gemeldet wurde, wurde ein Patch als Teil der Version 8.8.3 veröffentlicht, und die Sicherheitslücke CVE-2024-53900 wurde in der National Vulnerability Database (NVD) bekannt gegeben.

CVE-2024-53900 & CVE-2025-23061 Zeitleiste

  • 7. November 2024: Dat Phung hat eine kritische Schwachstelle in Mongoose entdeckt und einen Sicherheitsbericht an Snyk übermittelt. 
  • 26. November 2024: Mongoose hat Version 8.8.3 veröffentlicht, um diese Sicherheitslücke zu beheben. 
  • 2. Dezember 2024: Die National Vulnerability Database (NVD) hat CVE-2024-53900 für diese Sicherheitslücke veröffentlicht. 
  • 17. Dezember 2024: Bei der Analyse des Patches 8.8.3 von Mongoose fand Dat Phung eine Umgehung, die weiterhin RCE (Remote Code Execution) ermöglicht. Ein detaillierter Sicherheitsbericht wurde bei Tidelift eingereicht. 
  • 13. Januar 2025: Mongoose veröffentlicht Version 8.9.5 und führt einen verbesserten Patch ein, der die Umgehung wirksam beseitigt. 
  • 15. Januar 2025: Die National Vulnerability Database (NVD) veröffentlicht offiziell CVE-2025-23061 und unterstreicht damit den Schweregrad der neu identifizierten Sicherheitslücke.

Die Populate()-Methode von Mongoose

Mongoose bietet auch eine nützliche Funktion namens populate(), die die Möglichkeiten für die Arbeit mit Beziehungen zwischen Dokumenten verbessert. Während MongoDB-Versionen ≥ 3.2 über den Aggregationsoperator $lookup für Joins verfügen, bietet Mongoose mit populate() eine leistungsfähigere Alternative für das automatische Ersetzen einer Referenz durch die entsprechenden Daten aus verwandten Dokumenten. Dies ist besonders nützlich für die Verwaltung von Beziehungen zwischen verschiedenen MongoDB-Sammlungen, z.B. wenn ein Dokument ein anderes über seine _id referenziert. [2] 

JavaScript-Code zur Definition eines Mongoose-Schemas für einen Autor mit den Feldern Name, Alter und Lebenslauf
Autoren Schema
JavaScript-Code zur Definition eines Mongoose-Schemas für Bücher, einschließlich Titel, Beschreibung, Preis und Autorenreferenzen
Bücher Schema
JavaScript-Codefragment für eine Node.js-Route, die Buchdetails abruft und Felder für Autoren oder Rezensionen ausfüllt
Nodejs-Anwendung

Bei der Definition eines Schemas in Mongoose kann ein Feld so eingestellt werden, dass es mit der Option ref auf ein anderes Modell verweist. Die populate()-Methode wird dann verwendet, um das referenzierte Feld (eine ObjectId) durch das vollständige Dokument aus dem entsprechenden Modell zu ersetzen. In einer Buchhandelsanwendung verweist beispielsweise das Feld author im bookSchema auf das Dokument Author, und das Feld review auf das Dokument Reviews. Die populate()-Methode ermöglicht es Entwicklern, das Author-Feld (eine ObjectId) bei der Abfrage des Buchmodells durch das vollständige Author-Dokument zu ersetzen.

Die Funktion populate() ermöglicht es Entwicklern, das Feld author (das eine ObjectId ist) durch das vollständige Author-Dokument zu ersetzen, wenn sie das Buchmodell abfragen:

JSON-Darstellung eines MongoDB-Dokuments, das Buchdetails ohne erweiterte Autoreninformationen speichert
Keine Verwendung von populate()
JSON-Darstellung eines MongoDB-Dokuments mit erweiterten Autorendetails unter Verwendung der Funktion populate
Verwendung von populate()

Darüber hinaus unterstützt die populate()-Methode von Mongoose benutzerdefinierte Abfragen, um festzulegen, welche verwandten Dokumente abgerufen werden und wie sie abgerufen werden. Eigenschaften wie match und options ermöglichen es Entwicklern, verwandte Dokumente zu filtern, zu sortieren, einzuschränken und zu überspringen, und bieten so flexible Datenabrufmöglichkeiten.

JavaScript-Code zur Demonstration einer benutzerdefinierten Abfrage unter Verwendung der Populate-Funktion von Mongoose, um Autoren nach Alter zu filtern
Benutzerdefinierte Abfrage in populate() in Mongoose

CVE-2024-53900 Analyse

Im Rahmen des OPSWAT Cybersecurity Graduate Fellowship-Programms führte Dat Phung bei der Analyse von Mongoose zur Reproduktion bekannter CVEs eine umfassende Überprüfung der internen Funktionsweise der populate()-Methode durch, die eine Schlüsselrolle bei der Handhabung von Beziehungen zwischen MongoDB-Dokumenten spielt. Die populate()-Methode unterstützt sowohl String- als auch Objektargumente, und Entwickler können die Match-Option verwenden, um spezifische Filter auf die abgerufenen Daten anzuwenden:

JavaScript-Code zur Veranschaulichung der Verwendung des $where-Operators zum Filtern von Autoren nach Alter in einer Abfrage

Im obigen Beispiel ist die Match-Option ein Filterobjekt, das MongoDB-Abfrageoperatoren enthalten kann, wie im Abfrage- und Projektionsoperatoren - MongoDB-Handbuch v8.0 beschrieben. Ein bemerkenswerter Operator ist $where, der die Ausführung von JavaScript direkt auf dem MongoDB-Server ermöglicht. Diese Ausführung auf dem MongoDB-Server ist jedoch eingeschränkt und unterstützt nur grundlegende Operationen und Funktionen.

Tabelle mit JavaScript-Funktionen und -Eigenschaften, die für MongoDB-Map-Reduce-Operationen verfügbar sind

Dat Phung führte eine eingehende Analyse des Mongoose-Quellcodes durch, um den Arbeitsablauf der populate() -Methode zu verstehen. Er stellte fest, dass nach dem Aufruf der populate() -Methode für das Modell durch die Anwendung die Funktion populate() ausgelöst wird. Innerhalb dieser Funktion ruft Mongoose die Funktion _execPopulateQuery() auf, die die Abfrage mit dem Operator $where auf dem MongoDB-Server ausführt. Anschließend werden alle Dokumente aus der fremden Sammlung abgerufen und in den nächsten Schritten befüllt.

Screenshot einer VS-Code-Debugging-Sitzung zur Analyse der Ausführung einer Mongoose-Populate-Abfrage

Nach dem Abrufen der Daten aus MongoDB führt Mongoose die Callback-Funktion _done() aus, die _assign() aufruft, um die Daten vorzubereiten, bevor die beiden Modelle durch den Aufruf der Funktion assignVals() "zusammengefügt" werden.

Eine Debugging-Sitzung in VS Code zeigt hervorgehobenen JavaScript-Code im Zusammenhang mit der $where-Abfrage in Mongoose

Die Schwachstelle kann entstehen, wenn die abgerufenen Daten von der assignVals() -Funktion von Mongoose verarbeitet werden. Diese Funktion prüft, ob es sich bei der Match-Option um ein Array handelt und übergibt in diesem Fall jeden Operator an die sift() -Funktion. Die sift() -Funktion, die aus einer externen Bibliothek gleichen Namens importiert wird, verarbeitet diese Abfragen lokal auf dem Anwendungsserver. Diese lokale Verarbeitung stellt ein Sicherheitsrisiko dar, insbesondere bei der Verarbeitung von benutzergesteuerten Eingaben.

Eine VS-Code-Debug-Sitzung, die Variablenzuweisungen innerhalb einer JavaScript-Funktion zeigt

Um dies weiter zu untersuchen, änderte Dat Phung die Werte in der Match-Option, um sicherzustellen, dass die Bedingungen erfüllt waren, und rief so die Funktion sift() für eine zusätzliche Analyse des Datenflusses auf.

Ein JavaScript-Codefragment, das eine Mongoose-Abfrage mit einer $where-Filterbedingung demonstriert

Nachdem die Bedingung erfüllt war, wurde der Operator $where an die Funktion sift() übergeben.

Eine VS-Code-Debug-Sitzung, die gefilterte Werte in einer JavaScript-Funktion anzeigt

Die sift-Bibliothek ist ein leichtgewichtiges JavaScript-Dienstprogramm zum Filtern und Abfragen von Datensammlungen wie Arrays oder JSON-Objekten mit einer MongoDB-ähnlichen Syntax. In der offiziellen Dokumentation heißt es: "Sift ist eine kleine Bibliothek für die Verwendung von MongoDB-Abfragen in JavaScript". Die Funktion sift() wertet MongoDB-ähnliche Filteroperationen auf dem Anwendungsserver und nicht auf dem Datenbankserver aus, was das System bei der Verarbeitung nicht vertrauenswürdiger Eingaben erheblichen Sicherheitsrisiken aussetzen kann.

Ein einfaches JavaScript-Snippet, das Sift.js verwendet, um ein Array von Objekten anhand von Alterskriterien zu filtern
Ein Sift-Code-Beispiel

Bei der weiteren Analyse stellte unser Fellow ein Problem in der Funktion createDefaultQueryTester() der sift-Bibliothek fest. Diese Funktion wandelt jede Operation im Match-Array in ausführbare JavaScript-Funktionen um, die dann zum Filtern und Verarbeiten von MongoDB-Dokumentdaten vor Ort verwendet werden. Um dies zu erreichen, ruft createDefaultQueryTester() die Funktion createNamedOperation() auf und übergibt Operationen wie $where aus dem Match-Array als Argumente. 

Eine VS-Code-Debugging-Sitzung mit Schwerpunkt auf Abfrageoperationen und Funktionsausführung

Für jede Operation im Match-Array prüft createNamedOperation, ob die Operation unterstützt wird, und übergibt sie dann an die entsprechende Funktion.

Eine JavaScript-Debugging-Sitzung mit Abfrageoperatoren wie $where, $eq und $exists

Wenn die Operation $where ist, wird eine JavaScript-Funktion mit dem rohen "params"-Wert generiert, der vom $where-Operator im Match-Array abgeleitet ist und vom Benutzer gesteuert werden kann.

Ein hervorgehobenes JavaScript-Snippet zur Demonstration der Funktionsausführung bei aktivierter CSP (Content Security Policy)

CVE-2024-53900: Details zur Ausbeutung

Während MongoDB die Ausführung von JavaScript-Funktionen über die $where-Operation einschränkt, erlaubt die Funktion sift() die Ausführung dieser Funktionen ohne solche Einschränkungen. Diese fehlende Eingabevalidierung und -beschränkung stellt eine erhebliche Sicherheitslücke dar, da der Wert "params" - der direkt durch die Benutzereingabe gesteuert wird - ausgenutzt werden kann, was zu Code-Injection-Angriffen führen kann. Um dieses Problem genauer zu untersuchen, konstruierte Dat Phung die folgende Abfrage:

Ein JavaScript-Schnipsel, der eine Mongoose-Abfrage unter Verwendung der $where-Bedingung mit einer potenziell unsicheren Funktionsausführung zeigt

Zunächst konnte die Abfrage keinen anderen Prozess ausführen, was zu folgendem Fehler führte:

Ein MongoDB-Fehlerprotokoll, das einen Serverausführungsfehler aufgrund eines undefinierten globalen Verweises anzeigt

Dieser Fehler zeigt an, dass Mongoose versucht, die $where-Operation auf dem MongoDB-Server auszuführen, bevor die Kontrolle an die Funktion sift() übergeben wird. Aufgrund der Einschränkungen für JavaScript-Funktionen in der $where-Klausel von MongoDB tritt jedoch ein Fehler auf, der die Ausführung der Abfrage verhindert. Infolgedessen hält Mongoose den Prozess an, bevor er die sift() -Funktion erreichen kann.

Um diese Einschränkung zu umgehen, nutzte unser Kollege die "globale" Variable auf dem Anwendungsserver, die auf dem MongoDB-Server nicht existiert. Mit diesem Ansatz konnte er die Beschränkung auf dem MongoDB-Server umgehen und die Abfrage in die sift() -Funktion integrieren:

Ein Computerbildschirm mit dem Text "Der Code funktioniert nicht", der auf ein Problem bei der Codierung hinweist

Wenn Mongoose mit diesem Wert die $where-Operation auf MongoDB ausführt, bewirkt das Fehlen der Variablen "global", dass der ternäre Operator (typeof global != "undefined" ?global.process.mainModule.constructor._load("child_process").exec("calc") : 1), um 1 zurückzugeben und zu verhindern, dass MongoDB einen Fehler auslöst. Folglich wird die Abfrage auf dem MongoDB-Server ohne Probleme ausgeführt.

Wenn jedoch derselbe Wert die Funktion sift() erreicht, die auf dem Anwendungsserver ausgeführt wird, auf dem die "globale" Variable verfügbar ist, löst sie die Erstellung der folgenden Funktion aus:

Ein monochromer Bildschirm mit dem fettgedruckten Satz "hello world".

Konzeptnachweis für die Remote-Code-Ausführung (RCE)

Wenn ein Angreifer im Anwendungsbeispiel zu Beginn des Blogs die folgende Anfrage sendet, könnte er erfolgreich einen Angriff mit Remote Code Execution (RCE) ausführen:

Schwarzer und weißer Bildschirm, auf dem der Text "the new york times" in fetter Schrift erscheint
Diagramm zur Veranschaulichung der technischen Details der CVE-Schwachstellen von Mongoose, das den Datenfluss und die Sicherheitslücken aufzeigt

Das Video demonstriert den Proof of Concept für CVE-2024-53900, der Mongoose-Versionen vor 8.8.3 betrifft, bei denen eine ordnungsgemäße Eingabevalidierung fehlt, um den Missbrauch des $where-Operators zusammen mit der sift-Bibliothek zu verhindern.

Unvollständige Korrektur und CVE-2025-23061

Auf der Grundlage des Sicherheitsberichts von Dat Phung führte Mongoose einen Patch ein, der die zuvor identifizierte Schwachstelle (CVE-2024-53900) vor ihrer Veröffentlichung beheben sollte. Der entsprechende Patch(Automattic/mongoose@33679bc) fügte eine Prüfung hinzu, um die Verwendung von $where innerhalb der an populate() übergebenen match-Eigenschaft zu unterbinden.

Dieses Snippet prüft, ob die an populate() übergebene Match-Eigenschaft ein Array ist. Ist dies der Fall, durchläuft der Code jedes Objekt im Array, um festzustellen, ob es den Operator $where enthält. Wenn $where erkannt wird, wird ein Fehler ausgelöst, der verhindert, dass die bösartige Nutzlast an die riskante sift()-Funktion weitergegeben wird.  

Infolgedessen schlägt die Nutzlast, die CVE-2024-53900 ausnutzt, bei dieser Prüfung fehl, da ein Objekt im Match-Array $where enthält, wodurch es effektiv daran gehindert wird, sift() zu erreichen.

Während dieses Update die direkte Verwendung von $where innerhalb einer einzelnen Verschachtelungsebene korrekt blockiert, erkennt es $where nicht, wenn es in einen $or-Operator eingebettet ist - eine Struktur, die sowohl von MongoDB als auch von der sift-Bibliothek vollständig unterstützt wird.

MongoDB unterstützt den $or-Operator
Sift-Bibliothek unterstützt $or-Operator

Infolgedessen kann ein Angreifer $where unter $or verschachteln, um die einstufige Prüfung des Patches zu umgehen. Da Mongoose nur die Top-Level-Eigenschaften jedes Objekts im Match-Array prüft, bleibt der Bypass-Payload unentdeckt und erreicht schließlich die Sift-Bibliothek, was den bösartigen RCE ermöglicht.

Nutzdaten zur Umgehung des Fixes in Mongoose 8.8.3

Machbarkeitsnachweis für CVE-2025-23061

Um die Unvollständigkeit des Fixes zu verdeutlichen, hat Dat Phung die Beispielanwendung mit einer Version von Mongoose 8.9.4 (neuer als 8.8.3) neu erstellt. Durch die Verschachtelung von $whereinnerhalb einer $or-Klausel kann ein Angreifer die Prüfung erfolgreich umgehen und einen RCE erreichen.

Der Proof-of-Concept-Exploit demonstriert, wie CVE-2025-23061 in Mongoose-Versionen vor 8.9.5 ausgelöst werden kann, was einem Angreifer die Ausführung von beliebigem Code auf dem Server ermöglicht:

Milderung und Anleitung

Um die oben beschriebenen Schwachstellen zu beseitigen, stellen Sie bitte sicher, dass Ihr System auf die neueste Version von Mongoose aktualisiert ist.

MetaDefender Core mit SBOM Engine kann diese Sicherheitslücke erkennen

OPSWAT MetaDefender CoreMetaDefender Core ist mit fortschrittlichen SBOM-FunktionenSoftware Bill of Materials) ausgestattet und ermöglicht es Unternehmen, einen proaktiven Ansatz bei der Bewältigung von Sicherheitsrisiken zu verfolgen. Durch das Scannen von Softwareanwendungen und deren Abhängigkeiten identifiziert MetaDefender Core bekannte Schwachstellen, wie CVE-2024-53900 und CVE-2025-23061, innerhalb der aufgelisteten Komponenten. Dies ermöglicht es den Entwicklungs- und Sicherheitsteams, Prioritäten bei den Patching-Maßnahmen zu setzen und potenzielle Sicherheitsrisiken zu minimieren, bevor sie von böswilligen Akteuren ausgenutzt werden können. 

Unten sehen Sie einen Screenshot von CVE-2024-53900 und CVE-2025-23061, die von MetaDefender Core mit SBOM erkannt wurden:

Darüber hinaus können die CVEs auch erkannt werden von MetaDefender Software Supply Chainerkannt werden, das MetaDefender Core mit SBOM nutzt, um diese Schwachstellen zu identifizieren.

Bleiben Sie auf dem Laufenden mit OPSWAT!

Melden Sie sich noch heute an, um die neuesten Unternehmensinformationen zu erhalten, Geschichten, Veranstaltungshinweise und mehr.