ApostropheCMS uploadfs Azure-Backend legt SAS-Token auf Kontoebene in öffentlichen URLs offen
Zusammenfassung
Wenn uploadfs mit dem Azure-Backend und sas: true konfiguriert ist (eine unterstützte Konfiguration, die in uploadfs 1.25.0 eingeführt wurde), erstellt createContainer() den BlobServiceClient aus einer URL, die den vollständigen SAS-Query-String enthält. Abgeleitete Clients des Azure SDK v12 erben diesen Query-String. Infolgedessen gibt getUrl() eine Basis-URL zurück, die die vollständige SAS-Signatur auf Konto-/Container-Ebene (?sv=...&sig=...) enthält. Apostrophes attachment.url() stellt diesen Pfad jedem öffentlichen Anhangslink voran. Dadurch wird ein SAS-Token auf Container-Ebene (häufig sp=rwdlac für vollständigen Lese-, Schreib-, Lösch- und Auflistungszugriff) an alle Webseitenbesucher, einschließlich anonymer Nutzer, übertragen. Jeder, der eine Anhangs-URL sehen kann, kann für die Gültigkeitsdauer des SAS-Tokens jedes Blob im Container lesen, überschreiben, löschen und auflisten. Ein damit einhergehender Funktionsfehler (der Blob-Pfad wird nach dem Query-String angehängt, was zu fehlerhaften URLs führt) zeigt, dass dieser Codepfad nie durchgängig getestet wurde. Der standardmäßige Shared-Key-Modus und Backends, die nicht auf Azure basieren, sind nicht betroffen.
Verifiziert bei Commit 5a3746aaed49761e171c2cbfe793267c959829fd (uploadfs 1.27.0 im apostrophe-Monorepo).
Details
Ursache: Eine mit Anmeldeinformationen versehene Client-URL wird als öffentliche Basis-URL wiederverwendet. Die Kette:
- Client mit eingebetteten Anmeldeinformationen: azure.js#L123-L125 —
new BlobServiceClient("https://<account>.blob.core.windows.net?<SAS query string>"), wobeicluster.keyder vollständige SAS-String einschließlichsigist - Offenlegungsstelle: azure.js#L513-L520 —
getUrl()übernimmtgetContainerClient(...).getBlobClient('').urlalsbaseUrl; von SDK v12 abgeleitete Clients erben den SAS-Query-String, weshalbbaseUrlbereits?sv=...&sig=...enthält - Öffentliche Exposition: attachment/index.js#L694 —
attachment.url()=uploadfs.getUrl() + pathfür jeden gerenderten Anhangslink; attachment/index.js#L1503 —getBrowserData()liefertuploadsUrlauch an jede angemeldete Editorsitzung aus - Begleitender Fehler: Der Blob-Pfad wird nach dem Query-String angehängt (
/container/?sv=...&sig=XXX/attachments/id-name), weshalb diese URLs auch fehlerhaft sind — ein Hinweis darauf, dass der Codepfad 1.25.0 nie getestet wurde
Angriffsfläche: Jede öffentliche Seite, die Anhangs-URLs rendert (Bilder, Download-Links), sowie die an Editor-Sitzungen ausgelieferte uploadsUrl. Die Offenlegung erfolgt passiv und bedingungslos – das Opfer muss lediglich eine Seite ausliefern. Die Anmeldeinformationen verbreiten sich zudem über den HTML-Quelltext, Protokolldateien, Referer-Header und Zugriffs-Logs von CDNs/Proxys weiter.
Vorgeschlagene Abhilfemaßnahmen:
- Entfernen des Query-Strings vor dem Erstellen öffentlicher URLs:
const u = new URL(blob.svc.getContainerClient(...).getBlobClient('').url); u.search = '';(oderaccountUrl + '/' + containermanuell zusammensetzen) und Anhängen des Blob-Pfads an den Pfadnamen (pathname), nicht hinter den Query-String. - Dokumentieren, dass der SAS-Modus nach dem Prinzip der geringsten Berechtigungen (least privilege; schreibgeschützt, idealerweise
sr=bpro Blob) verwendet werden muss, und das Erzeugen kurzlebiger, schreibgeschützter signierter URLs pro Blob viagenerateBlobSASQueryParametersbevorzugen, anstatt ein Service-Level-SAS in permanente öffentliche URLs einzubetten.
PoC
Ein vollständiger PoC wurde als erster Kommentar unter (poc.js + README; offline, kein Azure-Konto erforderlich) bereitgestellt. Er repliziert die beiden Schritte der Bibliothek mit der deklarierten Abhängigkeit @azure/storage-blob@12:
npm install @azure/storage-blob@12 && node poc.js- Das Skript erstellt
new BlobServiceClient("https://myaccount.blob.core.windows.net?sv=...&sig=FAKESIGNATURE")genau wiecreateContainer(), wertet dann die Logik vongetUrl()aus (getContainerClient('uploads-container').getBlobClient('').url) und stellt sicher, dass die resultierende Basis-URL weiterhin den Parametersigenthält. - Beobachtete Ausgabe (Exit-Code 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
Die erzeugte URL legt sowohl das Token offen (sv…sig) als auch die fehlerhafte Pfadplatzierung dar. Ein Abgleich mit attachment/index.js bestätigt, dass diese URL öffentliche Seiten unverändert erreicht.
Auswirkungen
- Art des Problems: Unzureichend geschützte Anmeldeinformationen (CWE-522), die zur Offenlegung von Informationen führen (CWE-200). Ein SAS-Token auf Container-Ebene – das üblicherweise über Berechtigungen wie
sp=rwdlac(Lesen/Schreiben/Löschen/Auflisten/ACL) verfügt – wird jedem Webseitenbesucher, einschließlich anonymer Nutzer, offengelegt und ist für die gesamte Gültigkeitsdauer des SAS-Tokens (oft mehrere Jahre) gültig. Inhaber des Tokens können alle Blobs im Container lesen, überschreiben, löschen und auflisten; die Bibliothek wendet keine Einschränkung an. - Wer betroffen ist: Apostrophe-Instanzen, die uploadfs mit dem Azure-Backend und
sas: trueeinsetzen (eingeführt in 1.25.0; vorhanden bis einschließlich 1.27.0). Der standardmäßige Modus mit gemeinsam genutzten Schlüsseln (Shared Key) sowie andere Backends sind nicht betroffen. Wenn das SAS-Token schreibgeschützt bereitgestellt wurde, reduziert sich die Auswirkung auf das unauthentifizierte Lesen/Herunterladen aller Anhänge.
Gemeldet vom Kimi Security Team (bug-report@moonshot.ai).
Was zu tun ist
Aktualisieren Sie auf uploadfs Version 1.28.0 oder höher.
Betroffene Software
Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.
| Plattform | Paket | Anfällige Versionen | Behoben in |
|---|---|---|---|
| npm-Paket | uploadfs | >= 1.25.0, < 1.28.0 | 1.28.0 |
Verweise
- https://github.com/apostrophecms/apostrophe/security/advisories/GHSA-hhph-8536-gfq5
- 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/uploadfs@1.28.0
- CVSS-Vektor
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L- Schwäche (CWE)
CWE-200, CWE-522- Plattform
- npm
- Paket
uploadfs- Veröffentlicht
- 20.10.2026
- Aktualisiert
- 20.10.2026 21:30
Quellen und Lizenzen · Von DockRay bearbeitet oder übersetzt; Rechte und Lizenzen der Quellen bleiben erhalten.
OSV / GitHub Advisory Database - GHSA-hhph-8536-gfq5 - CC BY 4.0
Schwachstellenhistorie: uploadfs
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.
Dies ist die einzige bekannte Schwachstelle dieses Pakets.
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.