Исследователи ExPatch раскрыли сохранённую XSS-уязвимость в HTML-экспорте Telegram Desktop: специально подготовленная кнопка бота могла превратиться в JavaScript после сохранения чата и открытия файла в браузере. Исправление вошло в Telegram Desktop 6.9.4 beta и 7.0.1 stable ещё в июле, но HTML-файлы, созданные уязвимыми версиями, после обновления клиента сами не меняются.

Инлайн-кнопка обходила экранирование при экспорте Telegram Desktop
Причина уязвимости оказалась в одной операции внутри генератора HTML. Telegram Desktop корректно экранировал текст сообщений, имена отправителей и другие поля, чтобы символы вроде < и > отображались как обычный текст. Для подписи кнопки из inline-клавиатуры эта обработка не применялась.
Исследователи ExPatch нашли в export_output_html.cpp прямую запись button.text.toUtf8() без вызова функции SerializeString(). В самом клиенте Telegram такая строка оставалась текстом. После экспорта тот же фрагмент попадал в HTML-документ, где браузер уже мог интерпретировать HTML-теги и JavaScript как исполняемый код.
Уязвимость относится к классу stored XSS — сохранённый межсайтовый скриптинг. В обычном веб-сервисе такой код хранится на сервере и запускается при просмотре страницы. Здесь роль хранилища выполняла история Telegram, а точкой выполнения становился локальный HTML-файл, созданный через функцию экспорта.
Подробный технический разбор опубликовали исследователи ExPatch. По их оценке, проблема присутствовала в стабильных сборках примерно два года и четыре месяца — начиная с Telegram Desktop 4.15.1, выпущенного в марте 2024 года.
Пересланное сообщение могло перенести скрытый код в другой чат
Механика атаки была необычной из-за поведения inline-клавиатур. Бот мог создать сообщение с URL-кнопкой, а при пересылке такого сообщения Telegram сохранял кнопку вместе с её подписью. Самому боту не требовалось состоять в целевой группе.
Почему код мог долго оставаться незаметным? Telegram Desktop отображал подпись кнопки через собственный интерфейс и не передавал её браузерному движку. Потенциально опасный фрагмент превращался в исполняемый JavaScript лишь после того, как пользователь экспортировал историю в HTML и открыл полученный документ браузером.
По сценарию ExPatch одна пересылка могла оставить подготовленное сообщение в истории группы на месяцы или годы. Если позднее этот участок истории попадал в HTML-экспорт, браузер выполнял внедрённый код при открытии страницы.
Исследователи сообщили Telegram о проблеме 3 июня 2026 года. Telegram подтвердил отчёт 1 июля и предложил вознаграждение в размере 500 долларов; авторы исследования попросили направить его на благотворительность.
JavaScript получал доступ к сообщениям внутри открытого HTML-файла
В демонстрации ExPatch внедрённый скрипт мог прочитать сообщения и метаданные, уже присутствующие в открытой странице: имена отправителей, временные метки, название и тип чата, а также часть локальной информации о файле. Эти данные затем можно было отправить на внешний сервер.
Сценарий затрагивал содержимое конкретного HTML-документа. Telegram Desktop разбивает длинные экспорты на файлы примерно по 1000 сообщений, поэтому запуск кода в одной странице не давал автоматического доступа ко всей истории аккаунта.
Скрипт мог менять отображаемую страницу: подменять текст сообщений, даты, имена отправителей или показывать фальшивую форму. При этом оригинальная история на серверах Telegram и сам сохранённый файл на диске не переписывались — изменения происходили в представлении страницы внутри браузера.
Исследователи оценили уязвимость в 8,2 балла по CVSS 3.1, что соответствует уровню High в их собственной оценке. Публичного идентификатора CVE на момент публикаций 14–15 сентября не было, а Telegram не публиковал отдельный бюллетень безопасности по этой проблеме.
Подтверждённых данных об эксплуатации уязвимости против реальных пользователей исследователи не представили. Их проверка проводилась на собственных аккаунтах и тестовых группах.
Исправление вошло в Telegram Desktop 6.9.4 beta и 7.0.1 stable
Исправление оказалось компактным: разработчик Telegram Desktop John Preston добавил недостающее экранирование для текста inline-кнопок. Патч находится в коммите 8457d13a с сообщением Fix escaping in HTML export of keyboards.
Коммит был подготовлен 30 июня и получил публичную отметку 2 июля 2026 года. Первой помеченной сборкой с исправлением стала Telegram Desktop 6.9.4 beta, опубликованная 3 июля. В стабильный канал исправление вошло с Telegram Desktop 7.0.1 от 14 июля.
| Параметр | Данные |
| Затронутые стабильные версии | Telegram Desktop 4.15.1–6.9.3 |
| Первая исправленная beta | 6.9.4 |
| Первая исправленная stable | 7.0.1 |
| Исправляющий коммит | 8457d13a |
| Оценка ExPatch | CVSS 8.2 / High |
| CVE | Не присвоен на момент публикаций 14–15 сентября |
Исправленный код пропускает текст кнопки через SerializeString(), ту же функцию экранирования, которая уже использовалась для других строк при формировании HTML. Патч затронул и дополнительный путь внедрения данных в JavaScript-обработчик кнопки копирования.
Старые HTML-экспорты остаются отдельной зоной риска
Обновление Telegram Desktop меняет только то, как программа создаёт новые HTML-файлы. Уже сохранённые документы остаются обычными файлами на диске, поэтому клиент не переписывает их задним числом.
Именно этот нюанс сделал историю заметной спустя два месяца после выхода исправления. Профильные издания 14 и 15 сентября вновь обратили внимание на уязвимость: пользователь мог давно работать на исправленной версии Telegram Desktop и при этом хранить старый HTML-экспорт, созданный сборкой до 7.0.1. Если такой файл уже содержал подготовленную inline-кнопку, JavaScript сохранялся внутри документа.
Для архивов, служебных выгрузок и материалов, которые хранятся как локальные HTML-страницы, жизненный цикл файла отделён от жизненного цикла приложения. Патч закрывает генерацию опасной разметки в новых экспортах, а старые документы сохраняют исходное содержимое.
Уязвимость закрыта в клиенте, а публичного CVE пока нет
К 15 сентября техническая часть истории выглядит определённо: уязвимый путь находился в HTML-экспорте Telegram Desktop, исправление присутствует начиная с 6.9.4 beta и 7.0.1 stable, а ранее созданные HTML-файлы не меняются после обновления программы.
Менее ясной остаётся публичная сторона раскрытия. ExPatch сообщил о проблеме Telegram в июне, исправление появилось в июле, а подробный технический отчёт вышел 12 сентября. В release notes исправление отдельно не выделялось, собственного security advisory Telegram по этому случаю к свежим публикациям 14–15 сентября не было, идентификатор CVE также отсутствовал.
История показывает редкий тип долгоживущего риска: сама уязвимая генерация HTML уже закрыта, а созданный ранее файл способен сохранить прежнее поведение независимо от версии установленного клиента. Масштаб таких старых экспортов и наличие среди них файлов с внедрённым кодом публично неизвестны.