Перейти к содержимому
← Каталог golang WebSocket Security

WebSocket Message Injection (XSS via innerHTML)

WebSocket chat broadcasts unsanitized messages. Client renders via innerHTML, enabling XSS.

mediumgolangPro
Задача
# XSS через WebSocket: HTML-инъекция в чат ## Сценарий Вы аудируете интернет-магазин **SecureShop**. Команда добавила фичу чата в реальном времени на основе WebSocket: сервер принимает сообщения от подключённых клиентов и рассылает их всем активным сессиям. Команда уверена, что фича безопасна — для использования чата требуется авторизация. По данным внутреннего аудита, в админ-панели хранится конфиденциальная метка, и в системе есть бот-администратор, периодически проверяющий чат через сервисную форму отчётов; её требуется получить, имея только обычную учётную запись. ## Цель 1. Изучите, как сервер обрабатывает входящие сообщения чата перед рассылкой подключённым клиентам, и как клиентский JavaScript отображает полученные сообщения. 2. Найдите способ внедрить активный контент (HTML/JavaScript) через сообщение чата так, чтобы оно исполнялось в браузерах других подключённых клиентов. 3. Заманите бота-администратора в чат через сервисную форму отчётов и эксфильтруйте флаг из admin-панели на ваш Exploit Server. ## Теория Stored XSS через real-time канал (WebSocket-чат, push-уведомления, SSE) — особенно опасный класс уязвимостей: сообщение сразу попадает к **всем** подключённым клиентам, включая привилегированных пользователей и ботов-администраторов с активными сессиями. При этом уязвимость требует двух «забытых» защитных слоёв одновременно: серверной санитизации входящих сообщений (превращение `<`, `>`, `&`, кавычек в HTML-сущности) и клиентской вставки в DOM безопасным способом (через `textContent`, не через `innerHTML`). Если хотя бы один из слоёв на месте — атака не работает; если оба отсутствуют — любой клиент чата может выполнить произвольный JavaScript у других участников. **Уязвимый паттерн (сервер):** ```go // Сервер рассылает сообщение клиентам без экранирования HTML for client := range chatClients { client.WriteMessage(websocket.TextMessage, msg) // msg as-is } ``` **Уязвимый паттерн (клиент):** ```javascript // Клиент вставляет сообщение в DOM как HTML, а не как текст ws.onmessage = (e) => { div.innerHTML = e.data; } ``` При наличии stored XSS в admin-сессии атакующий может выполнить **same-origin-запросы** от лица admin-сессии (`fetch('/admin')` отправит admin-cookies автоматически — `HttpOnly`-флаг этому не мешает) и эксфильтровать ответ на любой внешний домен через `fetch` или `Image()`-загрузку. ## Точка входа атаки | Метод | Путь | Назначение | |-------|------|-----------| | GET / WS | `/chat` | WebSocket-чат, точка инъекции | | GET | `/admin` | Панель администратора с флагом (доступна только admin-сессии) | | GET / POST | `/report` | Форма отчёта — заманивает бота-администратора в указанный URL | **Учётные данные:** `demo` / `demo`
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru