telegramdesktop

Activity

Stars and mentions · Last 30 days, Oct 5 – Nov 3

GitHub stars289
Mentions10
09182736Oct 5Oct 19Nov 3
UTC days · repositories telegramdesktop owns1 repository

Top repositories

telegramdesktop’s repositories ranked by new stars, as on trending.

Loading

Contributes to

Repositories outside telegramdesktop’s account where telegramdesktop opened or reviewed pull requests in the past 365 days.

Who noticed telegramdesktop

Everyone who starred or forked telegramdesktop’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

10posts
Nov 40 posts
  1. Commit removing rlottie from Desktop: github.com/telegramdesktop/tdesktop/commit/619075… Commit removing rlottie from Android: github.com/DrKLO/Telegram/commit/4e1a61eca6c9b6ee… (3/3)

    1 like · 80 views
  2. Выгрузка истории чата через Telegram API в браузере: было 29 минут, стало две с половиной Я делаю сайт, который считает статистику переписки прямо в браузере. Обычно для этого нужен экспорт чата Telegram из Desktop, а с телефона его не сделать. Поэтому у меня есть второй путь, без компьютера и без файла. Человек входит со своего телефона, а страница сама выкачивает историю выбранного чата через Telegram API, то есть MTProto, как настоящий клиент. Работает это на mtcute поверх WebSocket к серверам веб-клиента Telegram, со своими api_id и api_hash с my.telegram.org. Три недели всё работало, но медленно. Я посмотрел в свою аналитику. Чат на 100–250 тысяч сообщений выгружался в среднем 33 минуты, а самый долгий занял 100. Всё это время человек должен держать вкладку открытой с горящим экраном, потому что в фоне телефон останавливает загрузку. Почти три четверти всего ожидания приходилось на большие чаты, хотя их всего пятая часть. Потом я сам выгрузил с телефона переписку на 52 тысячи сообщений, и страница честно написала, что осталось около 29 минут. Сегодня тот же чат выгружается за две с половиной. Ниже по порядку, что я перепробовал и что из этого реально сработало. Спойлер. Сработало не то, на что я больше всего надеялся. Куда уходило время История в Telegram отдаётся методом messages.getHistory по 100 сообщений за раз, листать нужно от новых к старым, передавая offset_id последнего полученного. Если спрашивать слишком часто, сервер отвечает FLOOD_WAIT_N и просит подождать N секунд. В первой версии я сделал паузу 300 мс между страницами, а после каждого такого ответа удваивал её, до двух секунд. Посчитаем. 1500 страниц, ответ сервера около 0,2 с, пауза после пары «подождите» уже 1,2 с. Выходит 1500 × 1,4 ≈ 35 минут, почти ровно медиана из аналитики. Ошибка видна сразу. Пауза только росла и никогда не уменьшалась. Один неудачный момент в начале, и дальше весь чат ползёт на минимальной скорости. Вторую вещь я заметил, только когда полез в исходники mtcute. По умолчанию там стоит floodWaiter с порогом 10 секунд, и все FLOOD_WAIT короче он пережидает сам и молча повторяет запрос. Мой код видел только длинные паузы. Получается, счётчик просьб подождать в моей аналитике показывал далеко не всё. Порог можно выключить на конкретный запрос: const res = await client.call(request, { floodSleepThreshold: 0, // не ждать молча, отдавать FLOOD_WAIT нам abortSignal: signal, // «Остановить» обрывает и запрос в пути }); sourcecraft.dev С таким вызовом я наконец увидел реальную картину на своём телефоне. Telegram не попросил подождать ни разу. Пауза между страницами 300 мс. А страница при этом шла три с половиной секунды. То есть почти всё время уходило на сам ответ сервера. У других людей, судя по той же аналитике, чистый ответ занимает около 0,2 с на страницу, а у меня вышло примерно в 15 раз дольше. На телефоне у меня включён VPN, и, видимо, дело в нём (дальний сервер, большая задержка). Но тогда я об этом ещё не думал и пошёл чинить ограничения, которых, как оказалось, не было. Takeout, или как выгружает Telegram Desktop У Telegram есть официальный механизм экспорта, через него работает «Экспорт истории» в Desktop. Открываешь сессию account.initTakeoutSession, оборачиваешь каждый запрос в invokeWithTakeout, и, если верить документации Telethon, лимиты становятся мягче. Сколько именно, Telegram не пишет. Сразу открыть такую сессию не получится. Если вход свежий (а у меня он всегда свежий, человек только что ввёл код), сервер отвечает TAKEOUT_INIT_DELAY и шлёт на все устройства служебное сообщение о запросе экспорта. Под ним есть кнопка «Разрешить». Нажал на телефоне, вернулся во вкладку, и следующая попытка открывает сессию сразу. Я сделал так. Выгрузка большого чата (от 10 тысяч сообщений) идёт обычным путём, а страница показывает плашку с просьбой нажать «Разрешить» и раз в 20 секунд, плюс каждый раз при возвращении на вкладку, пробует открыть takeout. Открылся, и со следующей страницы запросы идут через него. Чаще спрашивать не стал. Каждый initTakeoutSession на свежем входе может прислать ещё одно служебное сообщение, и заваливать человеку чат «Telegram» не хотелось. Сколько их приходит на самом деле при таком опросе, я, если честно, не считал. Первая версия с takeout не ускорила ничего. Я полез в исходники экспорта Telegram Desktop и нашёл два отличия. Desktop сначала запрашивает messages.getSplitRanges, получает диапазоны id сообщений и оборачивает каждый getHistory ещё и в invokeWithMessagesRange. Документация просит того же. Второе отличие в том, что пауз между страницами там нет совсем, единственная константа задержки закомментирована. В mtcute обёртка уже есть, это параметр withMessageRange: const session = await client.initTakeoutSession({ messageUsers: true, messageChats: true, messageMegagroups: true, }); const splits = await session.call({ _: 'messages.getSplitRanges' }); const res = await session.call(request, { floodSleepThreshold: 0, withMessageRange: splits[range], }); sourcecraft.dev Есть тонкость с диапазонами. Id сообщений в личных чатах и обычных группах общие на весь аккаунт, поэтому чат приходится листать по всем диапазонам, от последнего к первому. Если в диапазоне кончились сообщения, переходишь к предыдущему. У супергрупп нумерация своя, и Desktop берёт для них только последний диапазон. Я сделал так же. Кстати, если в супергруппе пройти по всем диапазонам, ничего страшного не случится, просто будет несколько пустых ответов, но зачем. Помогло? Честно говоря, почти нет. Через takeout с диапазонами страница у меня шла те же три с половиной секунды. Логично, если время съедает сеть. Takeout снимает ограничения на число запросов, а я в них не упирался. Двенадцать страниц сразу Если один запрос идёт три секунды и сервер не жалуется, напрашивается очевидное. Слать несколько запросов одновременно. Только offset_id следующей страницы неизвестен, пока не пришла предыдущая. Тут выручает add_offset. Он пропускает указанное число сообщений от offset_id, так что от одной точки можно разом попросить страницы 0–99, 100–199, 200–299 и так далее. Пришли все, и новой точкой становится последнее сообщение последней полной страницы. Если какая-то страница пришла неполной, значит, история (или диапазон takeout) кончилась, и остальные ответы пачки можно выбросить. const pages = await Promise.allSettled( Array.from({ length: width }, (_, i) => send({ ...request, offsetId: anchor, addOffset: i * 100 }, { kind: i > 0 ? 'download' : undefined, // свой WebSocket на страницу }), ), ); sourcecraft.dev Второй вопрос, по какому соединению их слать. Можно по одному, MTProto спокойно держит несколько запросов в полёте. Но у mtcute есть пул соединений для загрузки файлов (kind: 'download'), и туда можно отправить любой RPC, а не только upload.getFile. Размер пула задаётся через connectionCount, я поставил восемь. Если задержка набегает на каждое соединение отдельно, несколько соединений должны помочь сильнее, чем несколько запросов в одном. Сравнивать эти два варианта отдельно я не стал, сразу сделал с пулом. Сколько страниц просить сразу? Я не знаю реального лимита и, кажется, никто снаружи не знает. Поэтому ширина подстраивается сама. Takeout стартует с четырёх страниц. После трёх пачек подряд без FLOOD_WAIT ширина растёт на две, до двенадцати, а на первое же «подождите» падает вдвое. Без takeout потолок три, там лимит заметно строже, около запроса в секунду. Так пишут авторы Telethon в коде iter_messages, где по умолчанию стоит wait_time в секунду для больших чатов, и у меня похоже. И пауза теперь тоже оттаивает: после «подождите» она удваивается, как раньше, но после 20 спокойных страниц уменьшается на пятую часть. Сначала я считал эти 20 по пачкам, а при ширине 12 это растягивалось на минуты. Пришлось считать по страницам. Вот что вышло на том же чате с того же телефона. Как выгружали Ответ сервера На страницу по одной странице, обычный путь ~3,5 с ~3,5 с по одной, через takeout с диапазонами ~3,4 с ~3,4 с по две, обычный путь ~2 с ~1 с по четыре, через takeout ~1,4 с ~350 мс разгон до двенадцати, через takeout ~0,4 с ~200 мс 52 тысячи сообщений за две с половиной минуты, вместо 29. Telegram за всю выгрузку один раз попросил подождать 19 секунд, ширина после этого упала и снова разогналась. Последняя строка, правда, не совсем честное сравнение. Ответ сервера там вдруг стал 0,4 с вместо 1,4, похоже, VPN в тот момент работал быстрее. Так что часть прироста подарила сеть, и сколько именно, я сказать не могу. На компьютере без телефона, по входу через QR, получилось так же быстро. Обычный путь без «Разрешить» тоже ускорился в несколько раз, но до takeout ему далеко: там больше трёх страниц сразу лучше не просить. Так что плашку с просьбой нажать кнопку я оставил главным советом на экране. Обновить, не выгружая заново Вторая половина работы была о повторной выгрузке. Человек посчитал чат в октябре, а в декабре хочет итоги года. Зачем снова тянуть 150 тысяч сообщений, если новых там от силы тысяч пять? Я стал сохранять переписку Telegram прямо на устройстве, в IndexedDB, сжатую через CompressionStream('gzip'). Получается около 40 байт на сообщение, тот самый чат на 52 тысячи занимает 1,9 МБ. На сервер копия не уходит, и для людей это важно. При обновлении страница качает от новых сообщений к старым, пока не дойдёт до последнего сообщения копии минус два дня. Почему не ровно с последнего? Потому что сообщения правят и удаляют, а ещё сообщение, от которого считаешь, тоже могут удалить. Поэтому два дня перекрытия я заменяю целиком свежей версией из Telegram, ничего не сшивая по сообщениям. Всё, что старше, берётся из копии как было. Удалённое за эти дни пропадёт, исправленное обновится, дубликатов не будет просто по построению. Склейке нельзя верить вслепую, и проверок у меня две. Сообщения окна из копии должны найтись в ответе Telegram хотя бы наполовину. А если у Telegram сообщений в чате заметно меньше, чем у меня (больше чем на 2 % и 20 штук), значит, историю почистили. В обоих случаях страница просто докачивает чат целиком с того же места. Отдельный сюрприз преподнесли личные чаты. Копию мог сделать собеседник, файлом экспорта Desktop. А id сообщений в личке у каждого из двоих свои, у меня сообщение может быть номер 5000, а у него то же самое сообщение, скажем, номер 31 000. Тогда сравниваю по содержимому (время до секунды, автор, текст), а новым сообщениям даю номера после старых. Ответы на сообщения из окна при этом сохраняют свою связь, на более старые теряют. Обновление чата, где за пару часов ничего не написали, у меня заняло одну страницу и 415 мс. Неделя переписки, по моей оценке, докачивается за несколько секунд. Ещё одна грабля, на которой я потерял полдня. Страница входа передаёт выгрузку основной странице через Cache Storage, и та, забрав файл, сразу удаляет его из кэша. Разбор успевал файл прочитать. А вот копию для обновления я делал из того же файла позже, и в Safari на iPhone она молча не сохранялась. Похоже, после удаления из кэша второй раз такой Blob прочитать уже нельзя. В Chromium всё работало, поэтому на компьютере я ничего не заметил. Теперь копия сжимается сразу на странице входа, пока строка ещё в памяти. Может, кто-то сталкивался и знает, где это описано? Я так и не нашёл. И мелочь напоследок. Кнопка «Остановить» срабатывала через 5–7 секунд и не с первого нажатия. Отмена проверялась только между страницами, а запрос в пути и пауза доживали до конца. Помог тот же abortSignal в параметрах вызова (он есть выше в первом примере) и проверка signal.aborted перед паузой. Что осталось непонятным. Сколько одновременных запросов выдерживает takeout на самом деле? У меня двенадцать прошли почти без пауз, но это один аккаунт и один вечер. И даёт ли сам takeout что-то при хорошей сети, где упираешься уже в лимиты, а не в задержку. Если кто-то мерил, мне было бы очень интересно сравнить.

  3. Warning: High-severity flaw in #Telegram Desktop! #CVE-2026-107181, CVSS 8.6. This flaw allows one-click file theft and #AccountTakeover. #Patch #Patch #Patch Update to v7.2.9 or later: github.com/telegramdesktop/tdesktop/releases

    1 repost · 122 views
  4. Reddit · · r/KibernetinisSaugumas · u/Sarunas · telegramdesktop/tdesktop

    Telegram Desktop spraga leidžia vienu paspaudimu perimti paskyrą (CVE-2026-107181) BeakSec tyrėjas aprašė aukšto pavojingumo spragą Telegram Desktop iki 7.2.8. Suklastota nuoroda per naršyklę gali priversti programą be patvirtinimo išsiųsti vietinius sesijos failus. Be vietinio slaptažodžio galima atkurti sesiją ir perimti paskyrą be 2FA. Pataisa yra 7.2.9 (2026-09-17). Aktyvaus masinio išnaudojimo kol kas nepatvirtinta. Atnaujinkite klientą, įjunkite vietinį slaptažodį ir apribokite, kas gali jus pridėti į grupes. Šaltinis beaksec.github.io CVE cve.org Atnaujinimas github.com/telegramdesktop/tdesktop/releases/tag/…

    2 points
  5. کامیت رفع این باگ: github.com/telegramdesktop/tdesktop/commit/db3405…

    3 likes · 251 views
  6. Telegram Desktop 7.2.9 corrige CVE-2026-107181 de robo de cuenta Un clic en un link dentro de un chat de grupo bastaba para que un atacante leyera cualquier archivo del equipo de la víctima y, con él, robara la sesión activa de su cuenta. El hallazgo, publicado por el investigador detrás del blog beaksec y catalogado como CVE-2026-107181, describe la vulnerabilidad de Telegram Desktop que convertía un enlace corriente en una llave para tomar el control de una cuenta. La falla combinaba dos errores que por separado no servían de mucho: una inyección en el canal interno que usa el cliente para hablar consigo mismo y un comando heredado de las herramientas de publicación de Telegram que nunca pidió confirmación. Juntos alcanzaban para exfiltrar los archivos de sesión sin que la víctima notara nada raro. TL;DR - Telegram Desktop parcheó CVE-2026-107181: un clic en un link robaba la sesión de la cuenta.- El fallo encadenaba una inyección de comandos en el socket IPC con el esquema interno interpret:.- Las versiones afectadas llegan hasta la 7.2.8, confirmada en el build 6.9.3 de Windows.- CVSS 3.1 calificó la falla con severidad 8.1 (alta), sin impacto en la disponibilidad.- La corrección llegó en la versión 7.2.9 con el commit db3405699f. Qué es Telegram Desktop Telegram Desktop es el cliente oficial de escritorio de Telegram para Windows, macOS y Linux, desarrollado por Telegram FZ-LLC. Sincroniza chats y sesión con la nube de la app y expone un esquema de enlaces tg:// para abrir comandos desde el sistema operativo, el canal exacto donde apareció la vulnerabilidad de Telegram Desktop. Qué pasó con la vulnerabilidad de Telegram Desktop El reporte técnico, firmado por el investigador que publica bajo el seudónimo beaksec, documenta el fallo hasta la versión 7.2.8 de Telegram Desktop y lo confirma en la build 6.9.3 para Windows. La CVE-2026-107181 recibió una puntuación de 8.1 sobre 10 en CVSS 3.1, con el vector AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N: ataque remoto, complejidad baja, sin privilegios previos, pero con interacción del usuario obligatoria, el clic sobre el link. Telegram corrigió el problema en la versión 7.2.9, identificada en el repositorio del proyecto con el commit db3405699f. El reporte siguió el proceso habitual de divulgación responsable: el investigador avisó antes de publicar los detalles técnicos, y la entrada del blog salió una vez que la corrección ya estaba disponible para todos los usuarios. El punto de partida del problema no está en el cifrado ni en los servidores de Telegram, sino en cómo dos procesos del mismo programa se hablan entre sí en la computadora de la víctima. Ahí arranca la cadena. Contexto e historia Cuando un usuario hace clic en un link tg://, el sistema operativo no sabe si Telegram Desktop ya está abierto: lanza un proceso nuevo de todos modos. Ese proceso nuevo intenta conectarse a un socket local; si lo logra, significa que ya hay una instancia activa, así que le entrega el link y se cierra. Esa comunicación entre procesos (IPC, por sus siglas en inglés) usa un formato propio y sencillo: una palabra clave, su argumento y un punto y coma que cierra la instrucción. Dentro de ese mismo canal interno vive interpret:, un esquema que el sistema operativo no reconoce como protocolo (no está registrado en ningún manejador externo) pero que el propio código de Telegram sabe interpretar al vuelo, igual que cualquier otro link de arranque. interpret: nació como herramienta interna: cuando el equipo publicaba una versión nueva, un script armaba un archivo de texto con el canal de destino y el archivo a enviar, y lanzaba Telegram Desktop señalando ese archivo. El cliente leía la instrucción y subía el build con su changelog al canal oficial, sin que nadie tuviera que arrastrar el archivo a mano. El archivo de instrucciones admite un campo from: que compara el id de la cuenta logueada contra el id esperado, pensado para que un operador no publique un release desde la cuenta equivocada. Pero esa comparación solo corre si la línea from: está presente: omitirla la salta por completo. El destino, controlado por el campo channel:, solo exige que sea un canal o un supergrupo real. EscenarioQuién lo activaResultadoUso original de interpret:Un script interno con el archivo de instrucciones ya en el disco del operadorPublica el build nuevo y el changelog en el canal oficial de TelegramUso malicioso vía inyección IPCCualquier remitente que logre colar un segundo comando en el linkLee un archivo local y lo envía a un chat que no controla la víctima, sin pedir confirmación Detalles técnicos El formato de serialización que usa el IPC de Telegram Desktop no escapa el punto y coma cuando ese carácter aparece dentro del propio argumento. Un link normal se convierte en una sola instrucción, algo conceptualmente así: OPEN:tg://resolve?domain=canal; Pero si la URL que recibe el proceso nuevo ya trae un punto y coma en alguno de sus parámetros de consulta, ese proceso igual la trata como una sola cadena (para él, el punto y coma es apenas un carácter más dentro de la URL) y la reenvía tal cual por el socket. La instancia activa, en cambio, no distingue ese matiz: corta la cadena recibida en cada punto y coma y trata cada fragmento como una orden independiente. Una URL con un punto y coma de más se convierte, del otro lado, en dos instrucciones: OPEN:tg://resolve?domain=canal;CMD:show; Esa es la inyección, el primer defecto de la cadena. El segundo defecto es a dónde puede apuntar la instrucción inyectada: el protocolo interno reconoce cuatro comandos en total, y tres son inofensivos (entre ellos CMD:, que solo acepta show y quit, así que lo peor que logra es cerrar la ventana). El cuarto es OPEN:, y ahí está el detalle real: acepta cualquier URL, sin filtrar el esquema. Por ahí es alcanzable interpret:, el esquema que lee un archivo de instrucciones del disco y envía el archivo que ese archivo nombra, sin verificar quién lo pidió ni mostrar un diálogo de confirmación. La falla combina un punto y coma sin escapar con un comando heredado de las herramientas de publicación. El siguiente diagrama resume el camino completo, desde el clic de la víctima hasta la fuga del archivo: sequenceDiagram participant V as Víctima participant N as Proceso nuevo participant A as Instancia activa participant T as Chat del atacante V->>N: hace clic en el link malicioso N->>A: conecta al socket local y reenvía el comando combinado A->>A: corta la cadena recibida en cada separador A->>T: interpret lee el archivo y lo envía sin confirmación Note over A,T: la víctima no ve ninguna alerta No hay forma directa de verificar este comportamiento específico desde afuera del proceso: la inyección ocurre enteramente en memoria, dentro del socket local, y no deja un registro visible para el usuario final. Por eso el único control efectivo es la versión del cliente instalada, no una señal que se pueda observar durante el ataque. > 💭 Clave: Leído en simple, el vector AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N dice: ataque por red, sin complejidad extra, sin privilegios previos, con un clic de la víctima, confidencialidad e integridad altas y cero impacto en disponibilidad. Impacto y análisis El impacto real de la vulnerabilidad de Telegram Desktop no está en que un atacante pueda leer un archivo cualquiera, sino en cuál: los archivos de sesión que Telegram Desktop guarda localmente permiten reconstruir una sesión activa sin pasar de nuevo por la verificación del teléfono. Quien logra que esos archivos lleguen a su propio chat puede operar la cuenta de la víctima como si fuera el dueño, sin pedirle ni una contraseña ni un código. La cadena requiere interacción humana (el clic sobre el link), por eso el vector CVSS marca UI:R en lugar de un ataque silencioso de cero clics. Pero el contexto típico de Telegram, grupos numerosos donde cualquier miembro puede tirar un link, hace que ese único clic sea fácil de conseguir: no hace falta ingeniería social sofisticada, alcanza con que el link se vea como cualquier otro enlace de Telegram. El reporte confirma el comportamiento en la build 6.9.3 de Windows. El código de IPC que lo hace posible (el socket de instancia única, el formato de serialización y el esquema interpret:) vive en la base de código compartida de tdesktop, así que no hay motivo técnico para asumir que macOS y Linux quedaban fuera del alcance; el investigador simplemente documentó y confirmó el caso en un sistema operativo. Una limitación real de la corrección: tapar el escape del punto y coma y agregar una confirmación a interpret: arregla esta cadena puntual, pero no audita el resto del protocolo interno. Si aparece otro comando con el mismo patrón, sin escapar separadores o sin pedir confirmación, el mismo tipo de cadena vuelve a ser posible. Qué sigue Telegram ya corrigió el fallo en la versión 7.2.9, así que la recomendación inmediata es simple: actualizar el cliente de escritorio. En Windows, macOS o Linux, abrí Configuración → Telegram Desktop y fijate en la versión que aparece al pie de esa pantalla: debe marcar 7.2.9 o superior. Si todavía marca 7.2.8 o una anterior, ese cliente sigue expuesto a la vulnerabilidad de Telegram Desktop hasta que lo actualices. El reporte no menciona explotación activa antes de la publicación, algo esperable en una divulgación responsable: la corrección sale primero, los detalles técnicos después. Tampoco hay, por ahora, un aviso oficial separado de Telegram más allá del cambio en el changelog de la página de releases del proyecto. Queda pendiente, eso sí, una auditoría más amplia del protocolo interno de Telegram Desktop: si interpret: escondía este problema durante años (nació como herramienta de un script de publicación, no como superficie expuesta a links externos), no está descartado que otros comandos del mismo canal merezcan una revisión similar. Probalo vos: abrí Telegram Desktop, entrá a Configuración y confirmá que la versión marque 7.2.9 o más antes de volver a abrir links de chats que no controlás. 📖 Resumen en Telegram: Ver resumen Preguntas frecuentes ¿Qué hace vulnerable a Telegram Desktop ante este ataque? La combinación de un formato de comunicación entre procesos que no escapa el punto y coma y un comando interno, OPEN:, que acepta cualquier URL sin filtrar el esquema, incluido el esquema privado interpret:. ¿Necesito hacer algo si ya actualicé a la versión 7.2.9? No. La versión 7.2.9 incluye la corrección del commit db3405699f y cierra la cadena de inyección descrita en CVE-2026-107181. ¿El fallo de IPC afecta también a la app móvil de Telegram? El reporte confirma el problema en Telegram Desktop para Windows, el cliente que usa el esquema tg:// y el socket IPC descrito. No cubre las apps móviles de Telegram, que no comparten ese mecanismo de instancia única por socket. ¿Qué es el esquema interpret: que explota la falla? Es un esquema de enlace interno, no registrado ante el sistema operativo, que Telegram Desktop usaba para publicar sus propias versiones: lee un archivo de instrucciones local y envía el archivo que ese archivo nombra a un canal, sin pedir confirmación. ¿Cómo sé si mi copia de Telegram Desktop quedó parcheada? Abrí Configuración → Telegram Desktop y revisá el número de versión: 7.2.9 o superior ya incluye la corrección de este fallo. ¿Qué pudo robar un atacante con este exploit? Los archivos de sesión locales de Telegram Desktop, suficientes para tomar el control de una cuenta sin volver a pedir el código de verificación del teléfono. Referencias - beaksec: Telegram Desktop, one-click account takeover via IPC injection: el reporte técnico original con el análisis completo de la cadena de explotación.- NVD: CVE-2026-107181: la ficha oficial de la vulnerabilidad, con el vector CVSS 3.1 y la severidad 8.1.- GitHub: telegramdesktop/tdesktop: el repositorio oficial del cliente, donde vive el código del IPC y el commit de la corrección.- GitHub: releases de tdesktop: el changelog donde figura la versión 7.2.9 con la corrección del fallo. 📱 ¿Te gusta este contenido? Únete a nuestro canal de Telegram @programacion donde publicamos a diario lo más relevante de tecnología, IA y desarrollo. Resúmenes rápidos, contenido fresco todos los días.

    1 comment
  7. One unescaped semicolon was enough to steal Telegram accounts --- published: true description: CVE-2026-107181 — a clicked link, an IPC separator nobody escaped, three files, and your session. Anatomy of an 8.1 whose fix shipped as a "rendering fix". tags: security, programming, cpp, privacy series: receipts --- On June 25, a researcher reported to ZDI: a single clicked https:// link could read three files from a Telegram Desktop user's machine and ship them to an attacker's channel. The three files are the entire account. By September 17 they were fixed, and the changelog that shipped the fix to hundreds of millions of users described a rendering improvement. The writeup landed October 3 (beaksec), the CVE on October 7 — CVE-2026-107181, CVSS 8.1 — and the public PoC this week. dev.to coverage, as of tonight: none. So here is the anatomy, because the bug itself deserves the attention the changelog refused to give it. Semicolons on a local socket Telegram Desktop registers the tg:// URL scheme. Click a tg:// link anywhere in your OS and the handler launches a second process, which connects to a local socket where your running instance listens, and forwards the URL. Single-instance IPC — a pattern older than most languages reading this. The serialization is homemade: keyword, argument, semicolon terminator. OPEN:tg://x?a=1;. The receiver splits at every semicolon and treats each fragment as a command. The semicolon is never escaped when the URL is embedded. The researcher's line is the whole bug, and one of the best one-sentence descriptions of an injection I have read: the URL "is only a carrier" — once data crosses into the record, "the boundaries inside the data stop being held by the structure and become characters in the text." tg://x?a=1;CMD:quit arrives as one URL. The running instance parses two commands. The chain, receipt by receipt !The attack chain: staging, the click, the reader, the haul — CVE-2026-107181 1. The staging. Attacker creates a supergroup; default privacy settings let them add the victim silently. They post three plain-text instruction files. Default auto-download pulls anything under 8 MiB into Downloads/Telegram Desktop/. The files omit the from: line — skipping the account-ID check — and name the attacker's channel as destination. 2. The click. Victim clicks a normal https:// link in chat. (Links clicked inside Telegram never reach the socket — the browser is the required relay.) The attacker's server answers 302 → tg://… carrying stacked injected commands, including ;OPEN:interpret:../../../Downloads/Telegram%20Desktop/instructions1.txt. Relative paths, because the download folder resolves from the data directory — no username needed. 3. The reader. interpret: is a legacy internal scheme wired to InterpretSendPath in support_helper.cpp — a helper from the release-publishing workflow that reads a file and sends it, with no authorization check and no confirmation (support_helper.cpp:673-680: if (!f.open(QIODevice::ReadOnly))). The injection point itself is the URL join in sandbox.cpp:295-297. 4. The haul. One click, three files: key_datas, D877F783D5D3EF8Cs, and its maps index. That is the salt-plus-wrapped-DEK, the MTProto authorization, and the index. Dropped into a fresh tdata folder on any machine, they are the victim's session — the exact equivalent of stealing a session cookie. A helper that "just reads files for the build pipeline" turned out to be a remote file-transfer service for anyone who could name a path. Dead code that can act is not dead code. It is an unadvertised API. This bug is fifty years old Strip the Telegram branding and the skeleton is the oldest injection class in the book: a serialization boundary where data is allowed to contain the delimiter. CSV formula injection. CRLF in mail headers. HTTP response splitting. Shell word splitting. SQL concatenation. Every one is "the payload contains the separator, and nobody escaped the separator." I hit the same class on a smaller stage writing a seatbelt for my own coding agent: a shell case pattern expanded $HOME while the agent's command contained the literal text — the boundary between pattern and data silently moved. And the modern member of the family is the one this column keeps returning to: prompt injection is separator injection where the delimiter is natural language and the IPC channel is the model's context window. Tool output that contains instructions works for exactly the same reason ;CMD:quit worked. "The boundaries stop being held by the structure" — swap "structure" for "system prompt" and the sentence ships in a 2026 agent incident report. The fix receipt is the lesson made code: Telegram's patch (commit db3405699f, "Remove legacy interpret path helper", 11 files, +126/−372) adds EscapeTo7bit/EscapeFrom7bit, percent-encoding every character below 32, above 127, or equal to % or ; — and drops local file paths entirely when a non-local URL shares the connection. Escape the delimiter. Kill the dead capability. Both, not either. Encryption that decrypts with nothing The second half of the writeup is quieter and, for my money, worse. Telegram encrypts local session data. The design: a data-encryption key (DEK) wraps your data; a key-encryption key (KEK) wraps the DEK; the KEK derives from your local passcode plus a salt. Sound. By default no passcode is set. The KEK therefore derives from an empty string — and the salt sits in plaintext in tdata/key_datas. So "encrypted at rest" here means: the key that decrypts everything is stored next to the thing it decrypts, wrapped in nothing. One of the three exfiltrated files is that file. The encryption never even slowed the attack down; the researcher just took the session, padlock included. This is the plausible-security-narrative problem in one artifact. "Sessions are encrypted locally" is a true sentence that means nothing — unless the KDF binds to a secret the user actually chose, it is obfuscation wearing encryption's clothes. Same rule I apply to journals and logs: a protection you can describe without naming a secret the attacker lacks is not a protection. The quiet fix The timeline, as published by the researcher: - June 25 — reported via ZDI - September 16 — vendor fixes independently (commit db3405699f) - September 17 — Desktop 7.2.9 ships. Changelog: a rendering fix. No advisory, no security note, no CVE. - September 30 — ZDI closes the case as already fixed; disclosure rights return to the researcher - October 3 — writeup. October 7 — CVE assigned. This week — public PoC. Users running 7.2.8 were never told there was a race between their update and a public exploit. Silent security fixes are a bet that the whole installed base auto-updates before the PoC circulates — and the bet is placed with other people's accounts. A changelog line costs nothing: "fixed a bug where a crafted link could read files." Vendors owe the advisory; the researcher clearly did the work. What to steal - Never string-concatenate IPC records. Length-prefix, or a structured encoding (JSON, protobuf) where the parser cannot confuse payload with framing. If you must hand-roll, do what the patch does: escape control characters on write, unescape on read. - Treat every URL-scheme handler as an untrusted entry point — it is reachable by every web page that can issue a redirect. - Delete capabilities that can act. A legacy helper with send-to-channel power is not "unused code," it is an API you forgot you published. - At-rest encryption binds to a user-chosen secret or it is obfuscation. Say which one yours is. - Changelogs carry security fixes, by name, at the severity they carry. Two honest limits The confirmed chain is Windows. The researcher tested 6.9.3 on Windows; the tg:// single-instance mechanism exists on macOS and Linux too, but the writeup does not confirm the full chain there, and I did not reproduce the attack anywhere — running injection against a live messaging app crosses my line, so my receipts are the researcher's PoC, the writeup's file-and-line citations, and the merged fix commit, not my own run. And the vendor-side story rests on one account. Telegram published no advisory, so everything in "the quiet fix" beyond the public commit — the ZDI dates, the rendering-fix changelog — comes from the researcher's writeup. I have written it as a timeline, not a verdict. The commit speaks for itself; the silence around it does too. Your turn Confess your homemade serialization: the CSV that grew commas, the pipe-delimited log that grew pipes, the CLI that trusted a filename. Which delimiter betrayed you — and what would it have cost if the data had been someone else's session?

    9 reactions · 19 comments
  8. @beingivish Yes here it is github.com/telegramdesktop/tdesktop/commit/db3405…

    2 likes · 857 views
  9. @Fsociety7FX Here is a fix by TG github.com/telegramdesktop/tdesktop/commit/db3405…

    1 like · 107 views

Achievements

Awards earned by the repositories telegramdesktop owns. Select an award to embed its badge.

No awards yet

Repositories earn awards by reaching the top three in a completed trending day or week.

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.