Несколько дней назад я обнаружил, что Telegram приложение на Windows показывает давно удаленные чаты. При том, что их не было видно ни на телефоне, ни в Linux клиенте. Я поделился этим с друзьями, которые увидели то же самое. При чем некоторые из этих чатов датировались аж 2016 годом.
Изначально не получалось найти закономерности, так как переписка сохранялась не полностью, и сам список чатов казался случайным. Сейчас я смог разобраться в том, как это работает, какие чаты не удаляются полностью. А для этого пришлось немного углубится в устройство групп Telegram.
Для оптимизации работы серверов, чаты разделены на несколько уровней. Изначально создаются обычные чаты (basic group). Затем, в зависимости от увеличения количества участников, сообщений и видеоконференции уровень может повысится до супергруппы (supergroup). Повысить уровень чата можно вручную вызовом метода messages.migrateChat, если вы являетесь его администратором.
С повышением уровня группы у чата меняется его id, а история полностью копируется. Такое поведение неоднократно замечали обычные пользователи, так как о смене уровня приходит уведомление "The group was upgraded to a supergroup", видимое до следующей отправки сообщений, а сама группа меняется цвет логотипа.
Я начал исследовать "удаленные чаты" по API, и заметил, что у всех них проставлен флаг "deactivated", и присутствует параметр migrated_to. Документация Telegram API прямо говорит, что эти чаты повысили уровень. Кроме того, история переписки обычно обрывалась добавлением участников или инициализацией видеоконференции.
Становится понятным, что я вижу именно те чаты, которые были инициализированы при их создании, а покидал я уже супергруппы. В этом и может крыться ошибка.
Повторяем баг и подтверждаем теорию
-
Создаем группу, добавляем участников, отправляем несколько тестовых сообщений.
-
Узнаем id чата специальными для этого ботами, либо в моем случае - с помощью PHP библиотеки danog/madelineproto.
-
Отправляем запрос messages.migrateChat.
К моему удивлению, оказалось, что библиотека danog/madelineproto этот метод не поддерживает, и пришлось самому добавить его в класс InternalDoc, расположенный в vendor/danog/madelineproto/src/InternalDoc.php
public function migrateChat(mixed $id)
{
return $this->wrapper->getAPI()->methodCallAsyncRead('messages.migrateChat', ['chat_id' => $id]);
}
-
Вызываем повышение уровня:
$migrateChat = $MadelineProto->migrateChat(-99999999);
В ответе получаем информацию о двух разных чатах - чат до повышения и после. И в изначальном чате теперь точно так же проставился флаг deactivated, в нём больше не осталось участников, и некоторые другие аномалии.
При этом, мы всё ещё можем запросить информацию по старому id, включая переписку.
На телефоне же мы видим сообщение "The group was upgraded to a supergroup", и замечаем, что цвет чата изменился с оранжевого на фиолетовый.
-
Дальше симулируем ситуацию, когда админ хочет покинуть чат, и выходит из группы. Но, не проставляет галочку "Delete for everyone", давая возможность участникам попрощаться.
И сразу после нажатия на кнопку Leave, следующим кадром, видно этот же чат, но со старым, оранжевым логотипом и подписью "Group is inaccessible"
Проверяем по API, и так же видим всю историю сообщений
При этом на телефоне этого чата всё так же не видно. А у оставшихся участников видно только сообщение о том, что кто-то вышел.
Заключение
Если я смог заметить такое поведение через официальное приложение от Telegram, то вероятно по API это можно было повторить уже давно. В случае, если администратор чата выходит из группы - история переписки до момента повышения уровня навсегда остаётся доступной по API всем её учаcтникам. И при активном использовании Telegram этих чатов может стать очень много. Такое поведение не только не очевидно, но и становится опасным тем, кто регулярно чистит историю переписок, и ощущая свою безопасность, может предоставить злоумышленнику доступ к аккаунту.
На данный момент - являясь администратором чатов нужно не забывать передавать право владения группы в случае ухода из неё. Либо заходить через Windows, и удалять чат у себя повторно. Тогда он скроется окончательно. Это будет продолжаться до тех пор, пока Telegram не обратит внимание на ошибку, и не перестанет возвращать информацию о чатах до повышения уровня.
Автор:
gaxcaz