ApostropheCMS: Löschung von Prototyp-Eigenschaften durch Projektionsausschluss in @apostrophecms/db-connect führt zu Denial of Service
Zusammenfassung
@apostrophecms/db-connect enthält eine In-Memory-MongoDB-Emulation, die von den SQLite-, PostgreSQL- und multipostgres-Adaptern verwendet wird. Dessen Hilfsfunktion unsetNestedField durchläuft einen vom Angreifer kontrollierten Pfad ohne Segmentvalidierung und ruft delete auf der aufgelösten Eigenschaft auf. Ein authentifizierter Benutzer mit geringen Rechten (jede Rolle mit view-draft, über die jeder Bearbeiter und Mitwirkende verfügt; reduziert auf jeden angemeldeten Benutzer, wenn guestApiAccess aktiviert ist) kann eine piece-type-REST-GET-Anfrage senden, deren project-Query-Builder einen Ausschluss-Schlüssel wie constructor.prototype.hasOwnProperty enthält. Bei einem SQLite- oder PostgreSQL-Adapter erreicht dieser Schlüssel unsetNestedField, wodurch Object.prototype aufgelöst und eine gemeinsam genutzte Laufzeitmethode gelöscht wird. Da diese Methode prozessweit geteilt wird, unterbricht die Löschung die Anforderungsverarbeitung für jeden Mandanten und Benutzer bis zum Neustart des Prozesses, was zu einem persistenten Denial of Service führt.
Ursache
Der Projektions-Query-Builder bereinigt ausschließlich Projektionswerte, niemals Projektionsschlüssel, sodass ein beliebiger Dotted-Key die Datenbankschicht erreicht. Auf SQLite- und PostgreSQL-Adaptern wird eine Ausschlussprojektion in JavaScript von applyProjection angewendet, das für jedes ausgeschlossene Feld unsetNestedField(result, field) aufruft. unsetNestedField teilt das Feld an . und durchläuft die Segmente ungeschützt: Anders als das Gegenstück setNestedField wird nicht einmal ein literales __proto__ blockiert, und keine der beiden Hilfsfunktionen blockiert constructor oder prototype. Da das Arbeitsobjekt ein von JSON.parse(JSON.stringify(doc)) erzeugtes Plain-Object ist, löst dessen constructor zum globalen Object auf, sodass ein Pfad wie constructor.prototype.<member> das geteilte Object.prototype erreicht und eine konfigurierbare Kernmethode löscht.
Affected functions (repository-relative paths):
- unsetNestedField packages/db-connect/lib/shared.js:119-129 (no segment guard; delete on resolved property)
- applyProjection packages/db-connect/lib/shared.js:164-216 (exclusion branch calls unsetNestedField per excluded key)
Reachability driver (consumer on a SQL adapter):
- project.launder / project.finalize packages/apostrophe/modules/@apostrophecms/doc-type/index.js:2003-2103
- getRestQuery packages/apostrophe/modules/@apostrophecms/piece-type/index.js:1139-1157
- SQLite adapter applyProjection call packages/db-connect/adapters/sqlite.js:906,980
Auswirkungen
Voraussetzungen: Ein authentifiziertes Konto mit view-draft (jede Bearbeiterrolle; jeder angemeldete Benutzer, wenn guestApiAccess: true) sowie eine Konfiguration mit SQLite-, PostgreSQL- oder multipostgres-Adapter. Der standardmäßige mongodb-Adapter übergibt die Projektion an den echten MongoDB-Treiber und ist nicht betroffen. Unter diesen Bedingungen löscht eine manipulierte GET-Anfrage eine vom Angreifer gewählte gemeinsame Prototyp-Methode (z. B. Object.prototype.hasOwnProperty, toString oder ein Mitglied von Array.prototype). Nach der Löschung schlagen reguläre Aufrufe wie obj.hasOwnProperty(...) im gesamten Prozess fehl, sodass der betroffene Node-Prozess bis zu einem Neustart keine Anfragen mehr bedienen kann.
Proof of Concept
The finding was reproduced by executing the shipped helper directly against the published db-connect source; a live consumer requires a SQLite or PostgreSQL adapter, an authenticated view-draft session, and at least one matching document.
- Authentifizierung als beliebiger Benutzer mit
view-draftauf einer Instanz mit dem Adaptersqlite,postgresodermultipostgres. - Senden eines piece-type-REST-Lesezugriffs mit einer Ausschlussprojektion, deren Schlüssel auf eine geteilte Prototyp-Methode abzielt.
- Beobachten, dass nachfolgende Anfragen prozessweit fehlschlagen, da die Methode gelöscht wurde.
GET /api/v1/@apostrophecms/article?project[constructor.prototype.hasOwnProperty]=0
Cookie: <authenticated view-draft session>
safe benign exclusion {title:0} leaves Object.prototype.hasOwnProperty intact
VULNERABLE exclusion projection deleted Object.prototype.hasOwnProperty (callableBefore=true, brokeEveryObject=true)
VULNERABLE exclusion projection deleted an arbitrary Object.prototype method (__pocMarker)
Angriffskette
- Exposition: Ein authentifizierter
view-draft-Benutzer ruft den EndpunktGET /api/v1/@apostrophecms/<piece-type>auf. - Kontrolle: Die Abfragezeichenfolge
project[constructor.prototype.hasOwnProperty]=0wird vonqs(mit deaktiviertemallowDots) in einen Schlüssel mit literalen Punkten geparst:{ 'constructor.prototype.hasOwnProperty': '0' }. - Pfad:
getRestQuerywendet die Query-Builder zuerst an;project.launderkopiert den Schlüssel unverändert und konvertiert nur den Wert zufalse;project.finalizeüberspringt den Falsy-Wert mitif (!val) continueund behält den Schlüssel bei; der Cursor speichert ihn als Projektion. - Schutzmechanismus: Der Override
publicApiProjectionläuft nur, wenncanAccessApi(req)falsch ist, und wird daher für authentifizierte Aufrufer übersprungen. Es gibt keine Allowlist, Segmentprüfung oder Prototyp-Sperre. - Primitiv: Auf SQLite- oder PostgreSQL-Adaptern nutzt
applyProjectionden Ausschlusszweig und ruftunsetNestedField(result, 'constructor.prototype.hasOwnProperty')auf, welchesObject.prototypeauflöst unddelete Object.prototype.hasOwnPropertyausführt. - Ergebnis: Eine geteilte Prototyp-Methode wird prozessweit entfernt; alle nachfolgenden Anfragen schlagen fehl.
Umgehungsanalyse
Die Schutzmechanismen wurden einzeln analysiert. Das Projektions-launder bereinigt nur Werte und belässt beliebige Schlüssel. Die Rechteprüfung publicApiProjection greift bei !canAccessApi(req) nicht für authentifizierte view-draft-Benutzer. Die Schleife in finalize bricht beim Ausschlusswert vorzeitig ab. unsetNestedField besitzt keine Segmentprüfung; weder constructor noch prototype werden blockiert, und constructor.prototype.<member> umgeht selbst die Teilprüfung __proto__. Da das Objekt von JSON.parse(JSON.stringify(doc)) stammt, zeigt constructor auf Object, und da Object.prototype.hasOwnProperty konfigurierbar ist, gelingt das Löschen. Die frühere Behebung von Prototype Pollution fügte nur in apos.util.set/get im separaten Paket apostrophe eine {__proto__, constructor, prototype}-Prüfung ein; db-connect blieb ungehärtet.
Betroffene Versionen
Ecosystem: npmPackage: @apostrophecms/db-connectConfirmed affected range: >= 1.0.0, <= 1.0.2Latest release checked: 1.0.2 (npm registry)Fix status: not fixed
Die ungeprüfte Hilfsfunktion unsetNestedField und der Aufruf von applyProjection sind in den stabilen Releases 1.0.0, 1.0.1 und 1.0.2 byte-identisch. Die SQLite- und PostgreSQL-Adapter rufen applyProjection pro Dokument auf. Die Vorabversionen (1.0.0-alpha.1, 1.0.0-alpha.2, 1.0.2-alpha.0) enthalten denselben Code. Die Ausnutzbarkeit setzt SQLite, PostgreSQL oder multipostgres voraus; der standardmäßige mongodb-Adapter ist nicht betroffen. Das Paket apostrophe deklariert @apostrophecms/db-connect@^1.0.1, was das betroffene 1.0.2 auflöst.
Vorgeschlagene Behebung
Sicherstellen, dass Pfade aus nicht vertrauenswürdigen Quellen nicht auf gemeinsame Prototyp-Objekte zugreifen können. Sowohl unsetNestedField als auch setNestedField in packages/db-connect/lib/shared.js sollten Pfade ablehnen, deren Segmente __proto__, constructor oder prototype enthalten, analog zur unsafePathSegments-Prüfung in apostrophe (apos.util.set/get). Alternativ sollten Hilfsfunktionen nur eigene Eigenschaften durchlaufen (z. B. via Object.prototype.hasOwnProperty oder Map). Als Übergangslösung können Bereitstellungen den nicht betroffenen Standard-Adapter mongodb verwenden oder den authentifizierten API-Zugriff auf vertrauenswürdige Rollen einschränken.
Gemeldet von zx (GitHub: @manus-pi).
Was zu tun ist
Aktualisieren Sie apostrophe auf Version 4.33.0 oder höher und @apostrophecms/db-connect auf Version 1.1.0 oder höher. Als Übergangslösung kann auf den standardmäßigen mongodb-Adapter gewechselt oder der Zugriff auf die REST-Endpunkte für nicht vertrauenswürdige Rollen gesperrt werden.
Betroffene Software
Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.
Verweise
- https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-j5rq-xfvr-p969
- https://github.com/apostrophecms/apostrophe/commit/9500b8b0e1d630d5e07fbb5fd2c25ed0943845ce
- https://github.com/apostrophecms/apostrophe/commit/f84fd41cbf6c22eb8d0008fc9c25df1f7130b350
- https://github.com/apostrophecms/apostrophe
- https://github.com/apostrophecms/apostrophe/releases/tag/@apostrophecms/db-connect@1.1.0
- https://github.com/apostrophecms/apostrophe/releases/tag/apostrophe@4.33.0
- CVSS-Vektor
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H- Schwäche (CWE)
CWE-1321, CWE-400- Plattform
- npm
- Paket
apostrophe, @apostrophecms/db-connect- Veröffentlicht
- 20.10.2026
- Aktualisiert
- 20.10.2026 21:23
Quellen und Lizenzen · Von DockRay bearbeitet oder übersetzt; Rechte und Lizenzen der Quellen bleiben erhalten.
OSV / GitHub Advisory Database - GHSA-j5rq-xfvr-p969 - CC BY 4.0
Schwachstellenhistorie: apostrophe
Alle veröffentlichten Schwachstellen dieses Pakets (npm-Paket), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.
- Einträge insgesamt
- 27
- Erste → letzte
- 09.2020 10.2026
- Ohne Fix
- 4
- In Angriffen ausgenutzt
- 0
Verteilung nach Schweregrad
- Kritisch 2
- Hoch 8
- Mittel 13
- Niedrig 4
Veröffentlichungen pro Jahr
- 2020: 2
- 2021: 2
- 2022: 0
- 2023: 0
- 2024: 0
- 2025: 0
- 2026: 23
-
ApostropheCMS: Löschung von Prototyp-Eigenschaften durch Projektionsausschluss in @apostrophecms/db-connect führt zu Denial of Service dieser Eintrag
Erkennen Sie Schwachstellen in Ihrer Anwendung
Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.