As reported by SecurityAffairs, researchers at ExPatch uncovered a stored cross-site scripting vulnerability in Telegram Desktop's HTML chat export feature that allowed malicious JavaScript to be injected through bot inline keyboard buttons — payloads that could remain dormant in chat history for months or years before detonating in a browser. This is a textbook example of how security sanitization gaps in data transformation pipelines create long-tail risk that persists well beyond the initial exposure window.
Why This Vulnerability Is Uniquely Dangerous
The most striking aspect of this flaw is its temporal decoupling. The injection happens at one point in time — when a bot-crafted message enters a chat via forwarding — but the execution happens months or years later when a user exports the conversation to HTML and opens it in a browser. This creates a massive detection blind spot:
The root cause is depressingly familiar: an existing sanitization function (SerializeString()) was applied to message text, sender names, and other fields — but simply not called for inline keyboard button text. This is the same class of omission vulnerability we see repeatedly in output encoding failures across web applications and desktop software alike.
Vulnerability Details
| Component | Telegram Desktop — HTML export module (export_output_html.cpp) |
| Flaw Type | Stored Cross-Site Scripting (CWE-79) |
| Root Cause | Inline keyboard button text written to HTML without passing through SerializeString() sanitizer |
| Attack Vector | Bot-crafted message forwarded into target chat; payload executes when export HTML is opened in browser |
| Impact | Full exfiltration of exported messages and metadata; page content manipulation |
| Prerequisites | Attacker controls a Telegram bot; target user exports chat to HTML and opens in browser |
| Persistence | Payload remains in chat history indefinitely until export — no expiration |
| CVE ID | Not specified in source reporting |
| CVSS Score | Not assigned in source reporting |
| Active Exploitation | Not confirmed in the wild as of report date |
Who Is Most at Risk
While casual Telegram users face some exposure, the real risk concentrates in specific populations:
- Journalists and activists who frequently export and archive chats for evidentiary or record-keeping purposes — these users are also the most likely targets of sophisticated threat actors
- Corporate users who use Telegram for business communications and export conversations for compliance or legal documentation
- OSINT researchers and investigators who archive chat exports from monitored channels, potentially opening attacker-seeded content
- Organizations in regulated industries where chat exports may be shared as evidence in legal proceedings — a compromised export could exfiltrate sensitive case data from law firm networks
Broader Implications: The Export Pipeline Problem
This vulnerability highlights an underappreciated attack surface: data export pipelines. Nearly every messaging platform, collaboration tool, and CRM offers export functionality. Each represents a transformation point where stored data is re-rendered in a new format — and each is a potential sanitization gap. We have seen analogous issues in Slack exports, Notion page exports, and Confluence space exports. Security teams should be auditing export functionality with the same rigor applied to input validation.
The other lesson here is about code reuse inconsistency. When a sanitization function exists in the same file but isn't applied to all output paths, the failure is often a result of incremental development — a new feature (inline keyboard buttons) was added without auditing it against existing security controls. Static analysis tools that flag unsanized output paths could have caught this. SAST integration in CI pipelines for desktop applications remains underutilized compared to web application security testing.
Shield53 Recommendations
Immediate Actions
- Update Telegram Desktop to the latest version immediately — check the official Telegram website or GitHub releases for the patched version
- Audit existing HTML exports: Treat any Telegram HTML chat export created before the patch as potentially malicious. Open them in a sandboxed environment or inspect the source HTML for
<script>tags or suspicious inline event handlers before viewing in a standard browser - Scan for injected payloads: Use a simple grep or regex search across stored export files:
grep -riE '<script|onerror=|onload=|javascript:' *.html - Disable JavaScript when opening untrusted HTML exports — use a browser with JavaScript disabled or a tool like
lynxorw3mfor text-only review of sensitive exports
Longer-Term Hardening
- Establish export handling policies: Any HTML or JSON export from messaging platforms should be treated as untrusted content and opened in isolated environments
- Deploy Content Security Policy headers on internal systems where exports may be uploaded or viewed — a strict CSP would block inline script execution even if injected content slips through
- For developers: Implement automated SAST scanning that specifically flags output paths missing sanitization calls. Tools like Semgrep can write custom rules to detect unsanized writes to HTML-generating functions
- For organizations: Include export pipeline security in your threat modeling exercises. Map every data transformation point where stored content is re-rendered in a new format
The Telegram Desktop team should be credited for what appears to be a responsive fix, but the real takeaway is that old exports remain dangerous. Unlike a typical patch-and-move-on scenario, this vulnerability leaves behind poisoned artifacts that no software update can remediate. Defender playbooks need to account for the reality that some vulnerabilities create persistent contamination that must be cleaned up file by file.