Średnia

ApostropheCMS uploadfs z backendem Azure ujawnia token SAS w publicznych adresach URL załączników

  • Ujawniono: 20.10.2026
  • Aktualizacja: 20.10.2026 21:30

Podsumowanie

Gdy uploadfs jest skonfigurowane z backendem Azure oraz opcją sas: true (obsługiwana konfiguracja wprowadzona w uploadfs 1.25.0), createContainer() tworzy BlobServiceClient na podstawie adresu URL zawierającego pełny ciąg zapytania SAS, a klienci pochodni w Azure SDK v12 dziedziczą ten ciąg zapytania. W rezultacie getUrl() zwraca bazowy adres URL zawierający pełną sygnaturę SAS konta/kontenera (?sv=...&sig=...), a attachment.url() w Apostrophe dołącza go jako prefiks do każdego publicznego linku do załącznika — ujawniając poświadczenie SAS na poziomie kontenera (zazwyczaj sp=rwdlac, czyli pełny dostęp do odczytu, zapisu, usuwania i listowania) każdemu odwiedzającemu witrynę, w tym użytkownikom anonimowym. Każdy, kto widzi adres URL załącznika, może odczytywać, nadpisywać, usuwać oraz listować każdy obiekt blob w kontenerze przez cały okres ważności tokenu SAS. Towarzyszący błąd funkcjonalny (ścieżka blobu jest dołączana za ciągiem zapytania, co generuje uszkodzone adresy URL) wskazuje, że ta ścieżka kodu nigdy nie była testowana całościowo. Domyślny tryb klucza współdzielonego (shared-key) oraz backendy inne niż Azure nie są dotknięte tym problemem.

Zweryfikowano na commicie 5a3746aaed49761e171c2cbfe793267c959829fd (uploadfs 1.27.0 w monorepozytorium apostrophe).

Szczegóły

Przyczyna źródłowa: adres URL klienta zawierający poświadczenia jest ponownie wykorzystywany jako publiczny bazowy adres URL. Przebieg łańcucha:

  • Klient z osadzonymi poświadczeniami: azure.js#L123-L125 — new BlobServiceClient("https://<account>.blob.core.windows.net?<SAS query string>"), gdzie cluster.key jest pełnym ciągiem SAS zawierającym sig
  • Miejsce wycieku: azure.js#L513-L520 — getUrl() przyjmuje getContainerClient(...).getBlobClient('').url jako baseUrl; klienci pochodni w SDK v12 dziedziczą ciąg zapytania SAS, więc baseUrl zawiera już ?sv=...&sig=...
  • Ujawnienie publiczne: attachment/index.js#L694 — attachment.url() = uploadfs.getUrl() + path dla każdego renderowanego linku do załącznika; attachment/index.js#L1503 — getBrowserData() przekazuje również uploadsUrl do każdej zalogowanej sesji edytora
  • Towarzyszący błąd: ścieżka blobu jest dołączana po ciągu zapytania (/container/?sv=...&sig=XXX/attachments/id-name), przez co te adresy URL są również uszkodzone — co dowodzi, że ścieżka kodu 1.25.0 nie była testowana

Powierzchnia ataku: każda publiczna strona renderująca adresy URL załączników (obrazy, linki do pobierania), a także uploadsUrl dostarczane do sesji edytora. Wyciek jest pasywny i bezwarunkowy — od ofiary nie wymaga się żadnych działań poza serwowaniem strony. Poświadczenie rozprzestrzenia się dodatkowo przez kod źródłowy HTML, logi, nagłówki Referer oraz logi dostępowe CDN i serwerów proxy.

Sugerowane środki zaradcze:

  1. Usunięcie ciągu zapytania przed tworzeniem publicznych adresów URL: const u = new URL(blob.svc.getContainerClient(...).getBlobClient('').url); u.search = ''; (lub ręczne złożenie accountUrl + '/' + container) oraz dołączanie ścieżki blobu do ścieżki (pathname), a nie za ciągiem zapytania.
  2. Udokumentowanie, że tryb SAS musi stosować zasadę najmniejszych uprawnień (tylko do odczytu, najlepiej sr=b dla pojedynczego blobu) oraz preferowanie generowania krótkotrwałych, podpisanych adresów URL tylko do odczytu dla pojedynczego blobu za pośrednictwem generateBlobSASQueryParameters zamiast osadzania tokenu SAS poziomu usługi w stałych publicznych adresach URL.

PoC

Pełny PoC zamieszczono w pierwszym komentarzu poniżej (poc.js + README; tryb offline, konto Azure nie jest wymagane). Odtwarza on dokładnie dwa kroki biblioteki przy użyciu zadeklarowanej zależności @azure/storage-blob@12:

  1. npm install @azure/storage-blob@12 && node poc.js
  2. Skrypt konstruuje new BlobServiceClient("https://myaccount.blob.core.windows.net?sv=...&sig=FAKESIGNATURE") dokładnie tak jak createContainer(), następnie ewaluuje logikę getUrl() (getContainerClient('uploads-container').getBlobClient('').url) i potwierdza, że wynikowy bazowy adres URL nadal zawiera parametr sig.
  3. Zaobserwowany wynik (kod wyjścia 0):
baseUrl: https://myaccount.blob.core.windows.net/uploads-container/?sv=2021-06-08&ss=b&srt=co&sp=rwdlac&se=2099-01-01&sig=FAKESIGNATURE
attachment URL as served to visitors: https://myaccount.blob.core.windows.net/uploads-container/?sv=2021-06-08&ss=b&srt=co&sp=rwdlac&se=2099-01-01&sig=FAKESIGNATURE/attachments/abc123-photo.jpg

Wygenerowany adres URL ujawnia token (sv…sig) oraz wykazuje nieprawidłowe umiejscowienie ścieżki. Weryfikacja z attachment/index.js potwierdza, że ten adres URL trafia na strony publiczne w postaci niezmienionej.

Wpływ

  • Czym jest problem: niewystarczająco chronione poświadczenia (CWE-522) prowadzące do ujawnienia informacji (CWE-200). Token SAS na poziomie kontenera — zazwyczaj posiadający uprawnienia sp=rwdlac (odczyt/zapis/usuwanie/listowanie/ACL) — zostaje ujawniony każdemu odwiedzającemu witrynę, w tym użytkownikom anonimowym, i pozostaje ważny przez cały okres życia tokenu (często lata). Posiadacze tokenu mogą odczytywać, nadpisywać, usuwać oraz przeglądać wszystkie załączniki w kontenerze; biblioteka nie stosuje żadnych ograniczeń.
  • Kogo dotyczy: witryn Apostrophe korzystających z uploadfs z backendem Azure i opcją sas: true (wprowadzoną w 1.25.0; obecną do wersji 1.27.0). Domyślny tryb klucza współdzielonego oraz inne backendy nie są dotknięte problemem. Gdy token SAS został utworzony wyłącznie z uprawnieniem do odczytu, wpływ ogranicza się do nieuwierzytelnionego odczytu i pobierania wszystkich załączników.

Zgłoszone przez Kimi Security Team (bug-report@moonshot.ai).

Co trzeba zrobić

Zaktualizuj pakiet uploadfs do wersji 1.28.0 lub nowszej.

Czego dotyczy

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

PlatformaPaczkaPodatne wersjePoprawka w wersji
Paczka npm uploadfs >= 1.25.0, < 1.28.0 1.28.0

Odnośniki

Ocena CVSS 5.6/10
Wektor CVSS
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L
Słabość (CWE)
CWE-200, CWE-522
Platforma
npm
Paczka
uploadfs
Ujawniono
20.10.2026
Aktualizacja
20.10.2026 21:30

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

OSV / GitHub Advisory Database - GHSA-hhph-8536-gfq5 - CC BY 4.0

Historia podatności: uploadfs

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

To jedyna znana podatność tej paczki.

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.