Breaking
SecurityDeveloping Story

Telegram export flaw left old files exposed

A patched Telegram Desktop bug hid JavaScript in exported HTML, letting old export files leak or rewrite their contents when opened.

··1 hour ago·7 min read
person using smartphone
Photo by Christian Wiediger on Unsplash

A chat export is usually the last copy anyone thinks about. It sits in a downloads folder, opened once and forgotten, a static record of a conversation. Researchers at ExPatch have shown that for Telegram Desktop users, some of those files were never really static: a message planted by a bot could carry hidden JavaScript that ran the moment the export was opened in a browser.

The flaw was fixed in July, but the fix only applies to new exports. Files produced by earlier versions of the app can still carry the script, and as of September 14 Telegram had published no guidance for users holding them.

What the export actually did

Telegram Desktop, the Windows, macOS, and Linux client, can save a single chat or an entire account's chats as HTML pages designed to be opened in a browser. The export code wrote message text, sender names, and other fields into those pages after escaping them — converting characters such as < so a browser displays them as text rather than interpreting them as code.

One field did not get that treatment. Bots can attach rows of buttons beneath their messages, a feature Telegram calls inline keyboards, and the bot decides what text appears on each button. Until the fix, that button text went into the HTML page unescaped, according to researchers Denis Rostilov and Aleksander Rostilov.

That gap let a bot place a script tag inside a button's label, padded with invisible characters so the button appeared empty in the Telegram Desktop build the researchers tested. The message looked ordinary in the chat itself, carrying a link button. The script only executed when the export file was opened in a browser.

How the payload traveled

The bot does not need to be a member of the chat it targets. A message whose only buttons are web links keeps those buttons when it is forwarded, so any member who forwards the bot's message into a group carries the script along with it, the researchers found. From there it sits in the chat history like any other message until someone deletes it — and can be exported months or years later, long after the original bot interaction is forgotten.

Once an export containing the message was opened, the script ran without any further click. It could read every message in that file, including sender names and timestamps, the chat's name, type, and member count, and the local file path, then send all of it to a server the attacker controlled.

Telegram Desktop splits long exports into files of 1,000 messages each, so a single file exposes only its own contents — not the whole chat, and not the Telegram account itself. The researchers examined only Telegram Desktop's HTML export and did not address the JSON export format or the export features in Telegram's other apps.

Rewriting the record

Reading messages was only half of it. The same script could rewrite what the page displayed. In the researchers' demonstration, it replaced the entire export with a fake Telegram "verification" form. The same control could alter dates, senders, or message text in a file someone was keeping as a record, they said.

The script did not change Telegram's own copy of the chat or the export file saved on disk — only what a browser rendered from that file. That distinction matters for anyone treating an HTML export as evidence or an archive: the underlying file is untouched, but what a reader sees when they open it is not trustworthy.

"We also have considered the possibility of a public disclosure, but we cannot approve it as disclosing even the already addressed issues could put more Telegram users at risk in the future. For instance, if information about a vulnerability is made public, malicious actors may attempt to exploit it, thereby causing financial harm to Telegram users,"

— Telegram Support, in an email dated July 1 that the researchers published as a screenshot.

The researchers read that message as a refusal to allow publication even after a fix. They say no non-disclosure agreement covered their report, and they published their writeup on September 12, after the fix had shipped.

Three conditions, one old file

Three things had to line up for the script to run: the HTML export had to be made with a Telegram Desktop version released before the fix, the message carrying the script had to fall within the exported chat, and the file had to be opened in a browser with JavaScript enabled. Miss any one of those, and the payload stays inert.

Whether a forwarded bot message lands in an export depends on how the export is made. Exporting a single chat from its menu includes every member's messages. A full-account export includes, by default, only the account owner's own messages in groups and channels, but all messages in one-to-one chats and chats with bots, according to the export code and Telegram's documentation.

That asymmetry narrows the risk in some cases and widens it in others. A full-account export of a large group is less likely to sweep in a forwarded payload, but the same export of a direct chat with a bot would capture everything either side sent.

The fix and the gap it left

The missing escaping was added in commit 8457d13a by Telegram Desktop developer John Preston. It was written on June 30 and reached the 6.9.4 beta on July 3 and the 7.0.1 stable release on July 14 — the first fixed versions published on GitHub.

The unescaped line had been present in stable releases since 4.15.1 in March 2024, a span of about two years and four months. The researchers reported the flaw to Telegram on June 3, two days after finding it, and say they tested it only on their own accounts and test groups. Their writeup does not claim that anyone used the flaw against real users.

The release notes for 6.9.4 and 7.0.1, the app's changelog, and Telegram's July 14 announcement of the update do not mention the fix. The Telegram Desktop repository on GitHub lists no security advisories, and there is no CVE identifier for the flaw. The researchers noted that as of September 11, and a search of public vulnerability databases by The Hacker News on September 14 found none. The researchers rated the flaw 8.2 out of 10 on the CVSS 3.1 scale; no score from Telegram or from the U.S. National Vulnerability Database existed as of September 14.

  • Affected: Telegram Desktop 4.15.1 (March 2024) through 6.9.3
  • Fixed: 6.9.4 beta (July 3, 2026), 7.0.1 (July 14, 2026) and later
  • Export files split at 1,000 messages each
  • Researchers' CVSS 3.1 score: 8.2 out of 10
  • Unescaped line present in stable releases for about two years and four months

What the researchers advise

The researchers' guidance is straightforward. Update Telegram Desktop to 7.0.1 or later, or to 6.9.4 or later on the beta channel. After updating, export again any chats that were exported to HTML before the fix, or open the old files only with JavaScript disabled.

They also advise treating any HTML export made before the fix as untrusted — especially one from a large group where the origin of each message is hard to check. Until the app is updated, they see no reason to create new HTML exports, since only exports produced by the older code carry the flaw.

Telegram confirmed the flaw on July 1 and offered a bug bounty, which the researchers declined and asked to be given to charity. They requested a coordinated publication date and offered to stay silent until the patch shipped. Telegram's published bug bounty rules say vulnerabilities "disclosed to the public or to third parties before they are addressed" are not eligible for a bounty; the page says nothing about publication after a fix.

Why old exports still matter

The practical problem is that patching the app does not reach backward. Every HTML export produced by an affected version remains exactly as it was written, script included, and nothing in the update process flags those files or rewrites them. For most people that means a downloads folder with a handful of forgotten pages; for researchers, journalists, or anyone who exported a chat as a record of a dispute or an investigation, it means an archive whose displayed contents cannot be taken at face value.

The narrower exposure also cuts against complacency. A single file holds at most 1,000 messages, and the attack required a bot's message to survive into the exported range — but a forwarded message can sit in a group's history for years, so the window between planting and export is effectively unbounded. Anyone who opened such a file in a browser has already run the script; there is no scan that can tell them after the fact whether the export they read was genuine, because the script could have quietly altered the page as it loaded.

Telegram's stated concern was that disclosure could let malicious actors exploit unpatched users — even though the flaw had already been fixed and the researchers had waited for the patch. That reasoning leaves a gap the industry keeps running into: when a vendor withholds the technical details, users have no way to know which of their own files are affected or why they should stop opening them. Here, the most useful protective step is also the least visible — open old HTML exports with JavaScript off, or better, regenerate them from an updated client.

Until Telegram publishes its own guidance, the researchers' instructions are the only ones on offer, and they apply to anyone who has ever exported a chat that included a bot's message or a forwarded one. Checking is not complicated: update the app, then re-export anything that matters and discard the old files, or keep them only as inert, JavaScript-disabled documents.

#telegram#vulnerability#xss#html-export#data-security

Sources

Iliyas

Founder & Editor, Xploitwire

This article was written and reviewed against the sources listed above before publication, under editorial policies set by Iliyas. Read our Editorial Policy →

← Back to all stories