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-34048 — Route di bootstrap del terminale solo per admin controllate solo per lo stato di login, che consentono a un normale membro del team di guidare il backend del terminale in tempo reale di Coolify ed eseguire comandi sui server del team. | Kitploit
Strumenti/GitHubGitHub/0xmrma/cve-2026-34048
Autenticazione e AutorizzazioneEscalation di PrivilegiAnalisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingSicurezza CloudCommand and ControlRed Teaming
GitHub0xmrma/cve-2026-34048

CVE-2026-34048

Route di bootstrap del terminale solo per admin controllate solo per lo stato di login, che consentono a un normale membro del team di guidare il backend del terminale in tempo reale di Coolify ed eseguire comandi sui server del team.

1 mese faNon ancora revisionato

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
Vedi Repository

CVE-2026-34048

Le route di bootstrap del terminale riservate agli amministratori controllavano solo lo stato di login, permettendo a un normale membro del team di utilizzare il backend del terminale in tempo reale di Coolify ed eseguire comandi sui server del team.

Introduzione

Ho trovato questo problema mentre esaminavo Coolify, un PaaS self-hosted open-source, con una domanda di sicurezza molto diretta in mente:

L'accesso al terminale è effettivamente imposto al confine di fiducia del backend, o solo nell'interfaccia utente?

In questo caso, la risposta è stata negativa.

Coolify intendeva limitare l'accesso al terminale agli amministratori e proprietari del team, ma le route di bootstrap del terminale in tempo reale controllavano solo se l'utente era loggato. Ciò permetteva a un membro del team con privilegi bassi di soddisfare i controlli di fiducia del websocket del terminale e raggiungere l'esecuzione di comandi sui server del team.

Ho validato questo end-to-end in un laboratorio locale costruito dalla revisione vulnerabile e successivamente l'ho segnalato privatamente. Il problema ha ricevuto l'assegnazione CVE-2026-34048 con:

root@kitploit:~
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

Coolify: Coolify su GitHub
CVE: CVE-2026-34048

Questo ha interessato Coolify, un PaaS self-hosted open-source. Sul suo sito ufficiale, Coolify dichiara di avere 3.641+ clienti cloud, e si presenta come una piattaforma per distribuire siti web, database, applicazioni web e 280+ servizi con un clic. Il changelog ufficiale della v4.0 afferma inoltre che migliaia di aziende e persone hanno utilizzato Coolify in produzione per 1-2 anni.

photo0


Catena di Attacco

sessione membro del team con privilegi bassi -> /terminal/auth e /terminal/auth/ips controllano solo lo stato di login -> websocket in tempo reale si fida di queste risposte -> il membro enumera il server del team e l'UUID visibile della chiave SSH -> /terminal/ws accetta la sessione -> viene generato un PTY basato su SSH -> accesso shell sul server del team


Cosa Fa Coolify

Coolify è un PaaS self-hosted e una piattaforma di deployment.

Gestisce:

  • server
  • applicazioni
  • deployment
  • chiavi private
  • permessi del team
  • accesso al terminale dell'infrastruttura gestita

L'ultima capacità è quella importante qui.

Una volta che una piattaforma può aprire terminali su host gestiti, il suo modello di autorizzazione non è più solo logica applicativa. Diventa un confine di fiducia dell'infrastruttura.

La domanda importante non era se la pagina /terminal sembrasse riservata agli amministratori.

La vera domanda era:

Il percorso del terminale nel backend impone effettivamente lo stesso confine di autorizzazione quando viene creata la sessione websocket?

In questo caso, non lo faceva.


Perché Questo Bug Meritava Attenzione

Le funzionalità del terminale sono tra le superfici di maggior valore nel software per infrastrutture.

Perché?

Perché qualsiasi disallineamento tra:

  • autorizzazione UI
  • autorizzazione backend
  • logica di bootstrap websocket
  • esecuzione di comandi sull'host

può trasformare un normale utente dell'applicazione in un operatore con accesso shell.

È esattamente per questo che valeva la pena testare questa superficie.

Non cercavo crash casuali o bug di permessi estetici.

Cercavo una classe di fallimento più forte:

Una funzionalità riservata agli amministratori si basa su un controllo di fiducia del backend più debole di quanto suggerisca l'UI?

Quella era la domanda giusta.


Il Confine Su Cui Mi Sono Concentrato

Non ho affrontato Coolify fuzzando endpoint casuali sperando in qualcosa di interessante.

Il percorso più forte era identificare prima il confine a più alto rischio.

Per Coolify, quel confine era il flusso di lavoro del terminale:

  • l'UI dice che l'accesso al terminale è limitato
  • il servizio terminale è basato su websocket
  • i servizi websocket di solito hanno logiche di bootstrap separate per la fiducia
  • i comandi del terminale passano infine dallo stato dell'applicazione all'esecuzione sull'host

Questo rendeva le route di bootstrap il posto giusto dove guardare.

Ed è lì che si trovava il problema.


Causa Principale

La causa principale era un disallineamento di autorizzazione tra l'UI del terminale e le route di bootstrap del websocket del terminale.

Alla revisione vulnerabile:

  • GET /terminal era protetto da can.access.terminal
  • POST /terminal/auth controllava solo auth()->check()
  • POST /terminal/auth/ips controllava solo auth()->check()

Ciò significa che l'UI era bloccata dall'autorizzazione del terminale, ma il confine di fiducia del backend era bloccato dalla semplice presenza di una sessione autenticata.

Il servizio in tempo reale si fidava poi completamente di queste due route.

In docker/coolify-realtime/terminal-server.js:

  • verifyClient() inviava POST a /terminal/auth
  • la configurazione della sessione websocket inviava POST a /terminal/auth/ips
  • il gestore websocket accettava l'input di comando del terminale fornito dall'attaccante dopo aver controllato solo se l'host di destinazione appariva nell'elenco di host restituito

Questa è l'intera catena del bug.

Perché è sfruttabile

Perché un normale membro del team poteva costruire gli input necessari dalla superficie applicativa regolare:

  • /servers esponeva UUID di server visibili
  • /server/{uuid} esponeva ip, user e port in campi form renderizzati
  • /security/private-key esponeva UUID di chiavi private del team visibili
  • il percorso del terminale faceva riferimento alle chiavi tramite percorsi deterministici della forma:
root@kitploit:~
/var/www/html/storage/app/ssh/keys/ssh_key@<uuid>

Quindi il percorso di sfruttamento era diretto:

  • accedi come membro del team non amministratore
  • chiama /terminal/auth
  • chiama /terminal/auth/ips
  • enumera un server visibile
  • enumera un UUID di chiave visibile
  • connettiti a /terminal/ws
  • invia la stessa forma di comando SSH che il backend si aspetta
  • ricevi output shell da un host del team

Non è un disallineamento teorico. È un fallimento pratico dell'autorizzazione del backend.


Cosa Rende Questo un Problema di Sicurezza, Non Solo un Disallineamento dell'UI

La distinzione importante è la fiducia del backend e l'esecuzione dei comandi.

Molti bug appaiono come:

  • "il pulsante è nascosto"
  • "la pagina è bloccata"
  • "l'UI dice che non dovresti essere qui"

Da solo non basta.

La vera domanda è:

L'utente con privilegi inferiori può comunque soddisfare i controlli di fiducia del backend che contano?

In questo caso, la risposta era sì.

Questo non era:

  • un menu rotto
  • un controllo frontend mancante
  • un problema di routing estetico

Era:

  • autorizzazione di bootstrap websocket troppo debole
  • autorizzazione dell'host del terminale derivata da quel confine di fiducia debole
  • accesso shell reale sull'infrastruttura gestita

Ecco perché era un vero problema di sicurezza.


PoC

Ho validato questo in un laboratorio locale controllato costruito da:

root@kitploit:~
06f60c9a98bead0c932c6adf7fd43a45d9149048

Il laboratorio utilizzava:

  • URL base: http://127.0.0.1:18000
  • account membro con privilegi bassi: [email protected]
  • server di destinazione: localhost -> coolify-testing-host:22 as root
  • UUID chiave visibile: ssh
  • endpoint websocket: ws://127.0.0.1:6002/terminal/ws

Passo 1: conferma il confine UI

L'account membro non doveva avere accesso al terminale tramite la normale UI per amministratori.

Questo stabiliva il confine di sicurezza previsto.

Passo 2: chiama direttamente le route di bootstrap

Usando la sessione del membro, ho inviato:

  • POST /terminal/auth
  • POST /terminal/auth/ips

Entrambe hanno avuto successo.

/terminal/auth/ips ha restituito host autorizzati al terminale, inclusi:

root@kitploit:~
coolify-testing-host
host.docker.internal
localhost
127.0.0.1

Ciò ha dimostrato che le route di bootstrap del backend si fidavano della sessione del membro.

Passo 3: enumera metadati del server e delle chiavi

Dalle pagine autenticate normali, lo stesso membro poteva enumerare:

  • UUID di server visibili
  • campi di connessione del server
  • UUID di chiavi private del team visibili

Questo era sufficiente per guidare il percorso del terminale senza bisogno di divulgazione di materiale segreto delle chiavi.

Passo 4: apri il websocket del terminale

Usando la stessa sessione autenticata e il token XSRF, mi sono connesso a:

root@kitploit:~
ws://127.0.0.1:6002/terminal/ws

Passo 5: invia il payload del comando terminale

Il payload utilizzava lo stesso formato di comando previsto dal backend del terminale:

root@kitploit:~
{"command":["timeout 30 ssh -i /var/www/html/storage/app/ssh/keys/ssh_key@ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PasswordAuthentication=no -o ConnectTimeout=10 -o ServerAliveInterval=5 -o RequestTTY=no -o LogLevel=ERROR -p '22' 'root'@'coolify-testing-host' 'bash -se' << \\P0C\nprintf '__COOLIFY_POC_BEGIN__\\n'; id; whoami; hostname; printf '__COOLIFY_POC_END__\\n'\nP0C"]}

Passo 6: osserva l'output della shell remota

Il websocket ha restituito:

root@kitploit:~
pty-ready
__COOLIFY_POC_BEGIN__
uid=0(root) gid=0(root) groups=0(root)
root
efa027413801
__COOLIFY_POC_END__

Questa era la prova importante.

Non solo:

  • accesso alla route
  • non solo accettazione del websocket
  • non solo esposizione di metadati

Ma esecuzione effettiva di comandi sull'host gestito tramite il percorso del terminale riservato agli amministratori.


Perché Questo PoC Era Forte

Una parte di questa catena sarebbe già stata interessante.

Ad esempio:

  • accesso del membro a /terminal/auth
  • o accesso del membro a /terminal/auth/ips

Ma ciò avrebbe ancora lasciato spazio a facili smentite.

La validazione più forte era end-to-end:

  • sessione membro
  • successo del bootstrap backend
  • accettazione del websocket
  • creazione PTY
  • output shell remoto

Questo chiude il divario tra "bug di autorizzazione in teoria" e "impatto pratico sull'infrastruttura in realtà."

Ha anche reso molto più facile difendere la severità.


Severità e Classificazione

Questo problema è stato correttamente classificato come Critico.

La classificazione era:

  • CWE-862: Autorizzazione Mancante
  • CVSS:
root@kitploit:~
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

Ha senso.

L'affermazione non è che un attaccante non autenticato possa ottenere accesso shell dal nulla.

L'affermazione è che:

  • un membro del team con privilegi bassi
  • può soddisfare i controlli di fiducia del backend del terminale
  • e raggiungere l'esecuzione di comandi sull'infrastruttura del team

Questo è un cambiamento di ambito importante da fallimento RBAC applicativo a impatto sull'host gestito.

Quindi, anche se i privilegi sono bassi anziché nulli, il risultato rimane chiaramente critico.


Perché Valeva Comunque la Pena Segnalarlo

Alcune persone sottovalutano le vulnerabilità che iniziano con PR:L.

Questo è un errore quando la funzionalità interessata è l'accesso al terminale.

La vera domanda non è:

"L'attaccante era già loggato?"

La vera domanda è:

"Cosa può raggiungere quell'utente con privilegi inferiori una volta che l'autorizzazione del backend è sbagliata?"

In questo caso, la risposta era:

  • dati di selezione dell'host
  • fiducia di bootstrap del terminale
  • esecuzione PTY basata su SSH
  • accesso shell sui server del team

Questo va ben oltre un normale bug di permessi di un membro.


Analisi della Correzione

La correzione minima corretta è semplice:

  • applica can.access.terminal sia a POST /terminal/auth che a POST /terminal/auth/ips
  • assicurati che i membri non amministratori siano negati da entrambe le route
  • aggiungi copertura di regressione per:
    • utenti non autenticati negati
    • membri autenticati negati
    • amministratori e proprietari autorizzati consentiti

Questo risolve il fallimento immediato del confine di fiducia.

Nella mia patch di validazione locale, applicare il middleware di autorizzazione del terminale a quelle due route ha rimosso il percorso membro-al-terminale.

Ma la lezione più forte è che il backend non dovrebbe fidarsi delle stringhe di comando SSH controllate dall'attaccante come fonte primaria di metadati di destinazione.

L'hardening raccomandato è:

  • vincola le richieste del terminale a un identificatore di server o container autorizzato lato server
  • ri-valida l'autorizzazione quando il comando viene eseguito, non solo quando il websocket viene aperto
  • riduci la dipendenza dalla struttura del comando del terminale fornita dal client per le decisioni di sicurezza

Questo è il tipo di remediation che si desidera per una funzionalità del terminale:

  • correggi l'autorizzazione mancante immediata
  • poi stringi il modello di fiducia più profondo

Divulgazione

Questo problema è stato segnalato privatamente tramite il flusso di segnalazione di sicurezza di GitHub.

Il report includeva:

  • il disallineamento di autorizzazione
  • le route interessate
  • il percorso di fiducia del backend in tempo reale
  • una validazione funzionante in laboratorio locale
  • prova end-to-end che mostrava output shell remoto

Il problema è stato poi assegnato:

CVE-2026-34048


Cosa Insegna Realmente Questo Bug

La lezione principale qui è semplice:

un'UI riservata agli amministratori non conta se il canale di bootstrap del backend si fida di uno stato più debole.

Questa è la vera classe di problema.

  • Una pagina può essere protetta correttamente.
  • Un menu può essere nascosto correttamente.
  • Una schermata del terminale può essere bloccata correttamente.

Niente di tutto ciò conta se:

  • il percorso di bootstrap del websocket controlla solo lo stato di login
  • il backend del terminale si fida di quelle risposte di bootstrap
  • e la sessione risultante può raggiungere l'esecuzione di comandi sull'host

Una volta che una piattaforma gestisce l'infrastruttura, i disallineamenti di autorizzazione smettono di essere normali errori di controllo degli accessi. Diventano vulnerabilità con impatto sull'infrastruttura.

Questo è il vero insegnamento.


Punti Chiave

  • gli endpoint di bootstrap dei websocket sono veri confini di sicurezza
  • l'autorizzazione solo UI non è sufficiente per le funzionalità del terminale
  • utenti con privilegi bassi possono comunque produrre un impatto critico quando la fiducia del backend è sbagliata
  • l'enumerazione dei metadati del server più gli UUID visibili delle chiavi ha reso questo bug pratico
  • la validazione runtime end-to-end è importante quando si difende la severità
  • la correzione giusta è un'autorizzazione coerente del backend, non un blocco frontend più forte

Parole Finali

Questa vulnerabilità non riguardava un payload intelligente.

Riguardava l'identificazione del confine di fiducia giusto.

Coolify intendeva l'accesso al terminale come riservato agli amministratori. Ma il backend del terminale in tempo reale si fidava di route che controllavano solo se l'utente era loggato.

Da lì, un membro del team con privilegi bassi poteva guidare il percorso websocket del terminale e raggiungere l'esecuzione shell su un server del team.

Ecco perché questo è diventato CVE-2026-34048.

Scarica lo strumento