Wysoka

ApostropheCMS: Usuwanie składowych prototypu przez wykluczenie w projekcji w @apostrophecms/db-connect powoduje odmowę usługi dla całego procesu

  • Ujawniono: 20.10.2026
  • Aktualizacja: 20.10.2026 21:23

Podsumowanie

@apostrophecms/db-connect zawiera wbudowaną w pamięci emulację MongoDB używaną przez adaptery SQLite, PostgreSQL oraz multipostgres. Funkcja pomocnicza unsetNestedField przechodzi po kontrolowanej przez atakującego ścieżce z kropkami bez walidacji segmentów i wywołuje delete na rozpoznanej właściwości. Uwierzytelniony użytkownik o niskich uprawnieniach (dowolna rola posiadająca view-draft, którą ma każdy edytor i współpracownik; ograniczona do dowolnego zalogowanego użytkownika, gdy włączone jest guestApiAccess) może wysłać żądanie GET REST dla typu piece, którego konstruktor zapytań project zawiera klucz wykluczający, taki jak constructor.prototype.hasOwnProperty. W adapterze SQLite lub PostgreSQL klucz ten trafia do unsetNestedField, co prowadzi do rozwiązania Object.prototype i usunięcia współdzielonej metody środowiska uruchomieniowego. Ponieważ metoda ta jest współdzielona w całym procesie Node, jej usunięcie uniemożliwia obsługę żądań dla każdego najemcy i użytkownika aż do restartu procesu, powodując trwałą odmowę usługi pojedynczym żądaniem.

Przyczyna błędu

Konstruktor zapytań projekcji oczyszcza wyłącznie wartości projekcji, a nigdy klucze, w wyniku czego dowolny klucz zawierający kropki trafia do warstwy bazy danych. W adapterach SQLite i PostgreSQL projekcja wykluczająca jest stosowana w JavaScripcie przez applyProjection, która dla każdego wykluczonego pola wywołuje unsetNestedField(result, field). unsetNestedField dzieli pole na . i iteruje po powstałych segmentach bez żadnych zabezpieczeń: w przeciwieństwie do pokrewnej funkcji setNestedField nie blokuje nawet dosłownego __proto__, a żadna z funkcji pomocniczych nie blokuje constructor ani prototype. Ponieważ obiekt roboczy jest zwykłym obiektem wygenerowanym przez JSON.parse(JSON.stringify(doc)), jego właściwość constructor odwołuje się do globalnego Object, więc ścieżka constructor.prototype.<member> dociera do współdzielonego Object.prototype i usuwa konfigurowalną metodę bazową.

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

Wpływ

Wymagania wstępne: uwierzytelnione konto z uprawnieniem view-draft (dowolna rola edycyjna; dowolny zalogowany użytkownik, gdy włączone jest guestApiAccess: true) oraz konfiguracja korzystająca z adaptera SQLite, PostgreSQL lub multipostgres. Domyślny adapter mongodb przekazuje projekcję do natywnego sterownika MongoDB i problem go nie dotyczy. W tych warunkach pojedyncze spreparowane żądanie GET usuwa wybraną przez atakującego współdzieloną metodę prototypu (na przykład Object.prototype.hasOwnProperty, toString lub składową Array.prototype). Wykazaną konsekwencją jest trwała odmowa usługi w całym procesie: po usunięciu metody standardowe wywołania, takie jak obj.hasOwnProperty(...), zgłaszają błędy w całym Apostrophe, jego zależnościach i sterowniku bazy danych, przez co proces Node nie może obsługiwać żądań do momentu restartu.

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.

  1. Uwierzytelnij się jako dowolny użytkownik z view-draft w witrynie, której adapterem bazy danych jest sqlite, postgres lub multipostgres.
  2. Wyślij żądanie odczytu REST dla typu piece z projekcją wykluczającą, której klucz celuje we współdzieloną metodę prototypu.
  3. Zaobserwuj, że kolejne żądania kończą się niepowodzeniem w całym procesie z powodu usunięcia współdzielonej metody.
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)

Łańcuch ataku

  1. Ekspozycja: Uwierzytelniony użytkownik view-draft wywołuje punkt końcowy GET REST typu piece GET /api/v1/@apostrophecms/<piece-type>.
  2. Kontrola: Ciąg zapytania project[constructor.prototype.hasOwnProperty]=0 jest przetwarzany przez qs (przy wyłączonym allowDots) na pojedynczy własny klucz z dosłownymi kropkami: { 'constructor.prototype.hasOwnProperty': '0' }.
  3. Ścieżka: getRestQuery najpierw stosuje konstruktory zapytań; project.launder kopiuje klucz dosłownie i rzutuje tylko wartość na false; project.finalize pomija fałszywą wartość za pomocą if (!val) continue i zachowuje klucz; kursor zapisuje go jako projekcję.
  4. Blokada: Nadpisanie uprawnień publicApiProjection działa tylko wtedy, gdy canAccessApi(req) ma wartość false, więc jest pomijane dla uwierzytelnionego wywołującego; brak listy dozwolonych, weryfikacji segmentów czy ochrony prototypu.
  5. Prymityw: Na adapterze SQLite lub PostgreSQL applyProjection wybiera gałąź wykluczenia i wywołuje unsetNestedField(result, 'constructor.prototype.hasOwnProperty'), co prowadzi do rozwiązania Object.prototype i wykonania delete Object.prototype.hasOwnProperty.
  6. Wynik: Współdzielona metoda prototypu zostaje usunięta dla całego procesu Node, uniemożliwiając obsługę żądań do czasu restartu.

Analiza mechanizmów ochronnych

Przeanalizowano mechanizmy ochronne i żaden z nich nie blokuje tej ścieżki. Konstruktor projekcji launder oczyszcza tylko wartości i zachowuje dowolne klucze. Obejście uprawnień publicApiProjection jest uzależnione od !canAccessApi(req), więc nie jest aktywowane dla uwierzytelnionego użytkownika view-draft. Pętla po kluczach finalize kończy działanie przedwcześnie przy fałszywych wartościach. unsetNestedField nie posiada walidacji segmentów: ani constructor, ani prototype nie są blokowane, a ścieżka constructor.prototype.<member> omija nawet częściowe sprawdzenie __proto__. Ponieważ obiekt roboczy pochodzi z JSON.parse(JSON.stringify(doc)), jego constructor to globalny Object, a ponieważ Object.prototype.hasOwnProperty jest konfigurowalna, operacja usuwania kończy się sukcesem. Wcześniejsza poprawka prototype pollution dodała walidację {__proto__, constructor, prototype} tylko w apos.util.set/get w osobnym pakiecie apostrophe, pozostawiając db-connect bez ochrony.

Podatne wersje

  • Ecosystem: npm
  • Package: @apostrophecms/db-connect
  • Confirmed affected range: >= 1.0.0, <= 1.0.2
  • Latest release checked: 1.0.2 (npm registry)
  • Fix status: not fixed

Niezabezpieczona funkcja unsetNestedField oraz wywołanie gałęzi wykluczenia applyProjection są identyczne binarnie w wydaniach stabilnych 1.0.0, 1.0.1 oraz 1.0.2. Adaptery SQLite i PostgreSQL wywołują applyProjection dla każdego zwróconego dokumentu. Wersje przedpremierowe (1.0.0-alpha.1, 1.0.0-alpha.2, 1.0.2-alpha.0) zawierają ten sam kod. Podatność dotyczy wyłącznie instalacji z adapterem SQLite, PostgreSQL lub multipostgres; domyślny adapter mongodb nie jest podatny. Pakiet apostrophe deklaruje zależność @apostrophecms/db-connect@^1.0.1, która wskazuje na podatną wersję 1.0.2.

Sugerowane rozwiązanie

Należy zagwarantować, że niezaufane ścieżki pól nie będą miały dostępu do współdzielonych obiektów prototypu. Zarówno unsetNestedField, jak i setNestedField w packages/db-connect/lib/shared.js powinny odrzucać ścieżki zawierające segmenty __proto__, constructor lub prototype, na wzór zabezpieczenia unsafePathSegments w pakiecie apostrophe (apos.util.set/get). Alternatywnie funkcje mogą operować wyłącznie na własnych właściwościach (np. poprzez sprawdzenia Object.prototype.hasOwnProperty lub dostęp przez Map). Jako doraźne obejście można korzystać z domyślnego adaptera mongodb lub ograniczyć dostęp do punktów końcowych REST wyłącznie do w pełni zaufanych ról.

Zgłoszone przez zx (GitHub: @manus-pi).

Co trzeba zrobić

Zaktualizuj pakiet apostrophe do wersji 4.33.0 lub nowszej oraz @apostrophecms/db-connect do wersji 1.1.0 lub nowszej. Jako tymczasowe obejście można przełączyć się na domyślny adapter mongodb lub ograniczyć dostęp do końcówek REST do zaufanych ról.

Czego dotyczy

Kliknij technologię, aby zobaczyć wszystkie dotyczące jej podatności.

PlatformaPaczkaPodatne wersjePoprawka w wersji
Paczka npm apostrophe < 4.33.0 4.33.0
Paczka npm @apostrophecms/db-connect < 1.1.0 1.1.0

Odnośniki

Ocena CVSS 7.1/10
Wektor CVSS
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H
Słabość (CWE)
CWE-1321, CWE-400
Platforma
npm
Paczka
apostrophe, @apostrophecms/db-connect
Ujawniono
20.10.2026
Aktualizacja
20.10.2026 21:23

Źródła i licencje · Redakcja lub tłumaczenie: DockRay. Zachowano prawa źródeł i obowiązujące licencje.

OSV / GitHub Advisory Database - GHSA-j5rq-xfvr-p969 - CC BY 4.0

Historia podatności: apostrophe

Wszystkie opisane podatności tej paczki (Paczka npm), od najnowszej. Widać, czy to jednorazowa wpadka, czy paczka, której trzeba pilnować.

Wszystkie (27) w archiwum
Wszystkich wpisów
27
Pierwsza → ostatnia
09.2020 10.2026
Bez poprawki
4
Wykorzystywana w atakach
0

Rozkład istotności

  • Krytyczna 2
  • Wysoka 8
  • Średnia 13
  • Niska 4

Ujawnienia w latach

  1. 2020: 2
  2. 2021: 2
  3. 2022: 0
  4. 2023: 0
  5. 2024: 0
  6. 2025: 0
  7. 2026: 23
Istotność:
  1. ApostropheCMS: Usuwanie składowych prototypu przez wykluczenie w projekcji w @apostrophecms/db-connect powoduje odmowę usługi dla całego procesu ten wpis
    Wysoka · 7.1 CVE-2026-113666 < 4.33.0 4.33.0
  2. Wysoka · 7.3 CVE-2026-45011 = 4.29.0 brak poprawki
  3. Krytyczna · 9.8 CVE-2021-25979 >= 2.63.0, < 3.4.0 3.4.0

Dowiedz się, które podatności dotyczą Twojej aplikacji

Po podłączeniu integracji DockRay i włączeniu raportowania oprogramowania DockRay porównuje zgłoszone wersje komponentów ze znanymi podatnościami i powiadamia o potwierdzonych dopasowaniach. Zakres zależy od obsługiwanej technologii i dostępnych biuletynów.

Podłącz swoją aplikację
Newsletter DockRay

Bezpieczeństwo aplikacji w Twojej skrzynce

Najważniejsze podatności, konkretne zalecenia i praktyczne wskazówki dla Twoich aplikacji. Wybierz technologie i śledź to, co ma znaczenie dla Twojego projektu.

  • Codzienne zestawienie nowych podatności, także krytycznych.
  • Powiadomienia o ważnych aktualizacjach.
  • Praktyczne porady o bezpieczeństwie i monitoringu aplikacji.

Pozostaw puste, aby otrzymywać informacje o wszystkich technologiach.

Zapis jest bezpłatny. Wypiszesz się jednym kliknięciem w wiadomości.