Telegram Desktop One-Click Account Takeover: How IPC Trust Confusion Shattered Cryptographic Defenses

Telegram Desktop One-Click Account Takeover: How IPC Trust Confusion Shattered Cryptographic Defenses

SecurityVulnerability AnalysisClient Security

Sources:beaksec.github.io

Telegram’s local data encryption architecture is theoretically robust. User session data is encrypted using a dedicated Data Encryption Key (DEK), which is in turn safeguarded by a Key Encryption Key (KEK) derived from the user’s passcode. Yet on Windows desktops, a single malicious link was enough to bypass this entire cryptographic fortress. Security researcher beaksec disclosed CVE-2026-107181, a zero-interaction account takeover flaw in Telegram Desktop: by tricking a victim into clicking a crafted URI, an attacker could silently upload the victim’s core session files to a designated group, granting complete account takeover.

VulnCheck, serving as the CNA, assigned this vulnerability a CVSS 4.0 score of 8.6, compared to a base CVSS 3.1 score of 8.1. The discrepancy stems from CVSS 4.0’s heavier weighting of subsequent system-level ramifications triggered by minimal user interaction. The exploit succeeded because Telegram Desktop converged trusted internal commands and untrusted external inputs into the exact same unvalidated communication pipeline. When upstream components fail to treat external input as untrusted, the strongest cryptographic vault cannot withstand a collapsed boundary.

Unescaped Delimiter Exposes Internal Privileged Backdoor

The initial link in the attack chain involves improper neutralization of record delimiters (CWE-143) across the local single-instance socket. When a user clicks an external link while Telegram Desktop is already running, the operating system launches a secondary process to pass the URI. This new process connects to the running instance via a local socket, formatting the incoming URI as OPEN:<url>;. The primary instance parses this stream by splitting on semicolons into distinct instructions. The vulnerability lies in the lack of delimiter escaping: neither the assembly logic in sandbox.cpp:295-297 nor the command tokenization in sandbox.cpp:453-463 sanitized special characters. A crafted URI containing a semicolon—such as tg://x?a=1;CMD:quit—splits cleanly into two independent commands, allowing untrusted input to escape directly into internal execution logic.

Diagram: Attack chain from clicking a crafted link to victim session exfiltration. Source: beaksec.github.io Diagram: Attack chain from clicking a crafted link to victim session exfiltration. Source: beaksec.github.io

The injected command seamlessly hooks into the second link of the chain: the internal interpret: URI scheme. Under application.cpp:1162-1164, the client appends the referenced path to its execution queue. The subsequent InterpretSendPath routine (located in support_helper.cpp:673-680) reads the local file indicated by the instruction payload and transmits it to a predetermined channel or supergroup—entirely bypassing authorization checks and user confirmation dialogs. Originally developed as an internal update mechanism used by build/updates.py to deploy release builds, the protocol expected an optional from: field to match the active account. Crucially, when that field is omitted, the check is skipped entirely. This fragile parser effectively gifted arbitrary execution of internal privileged functions to external attackers.

Automatic Downloads Assemble a Deterministic Exploit Chain

While the vulnerability provided execution capability, weaponizing it into reliable account takeover required state-machine precision. The attacker first establishes a supergroup and adds the victim—a maneuver permitted by Telegram’s default privacy settings without requiring victim confirmation. Next, the attacker posts three plain-text instruction files to the group containing interpret: commands targeting the victim’s sensitive local files. Taking advantage of Telegram’s automatic download feature for attachments under 8 MiB, these files are silently saved to C:\Users\<user>\Downloads\Telegram Desktop\.

The interpret: protocol accepts relative paths resolved against Telegram’s working directory on Windows (%APPDATA%\Telegram Desktop). By supplying ../../../Downloads/Telegram%20Desktop/instructions.txt, the exploit traverses directly into the downloads folder, hitting the automatically fetched payloads without needing to discover the victim’s Windows username. The attacker then posts an HTTP link in the chat that issues a 302 redirect to the crafted tg:// payload. Once clicked, the injection executes instantly.

The three instruction files exfiltrate the critical artifacts necessary for session takeover: tdata/key_datas containing the unencrypted salt, the D877F783D5D3EF8Cs file located within a directory derived from default database naming conventions, and the corresponding maps index file. The directory string D877F783D5D3EF8C is not random; it is deterministically derived from the string data, as implemented in storage_file_utilities.cpp:241-250, producing identical folder names across every standard installation. When no local passcode is configured, the passcode defaults to an empty string. Armed with the stolen salt from key_datas, an attacker can execute the standard key derivation routine, recompute the KEK, decrypt the DEK, and recreate the victim’s MTProto session locally. Individually, automatic downloads, relative path parsing, and optional passcodes serve practical user experience goals; combined within the same context, they formed a lethal exploitation pipeline.

Four Source Code Fixes Rebuild Communication Boundaries

To neutralize this exploit chain, Telegram chose to eliminate the legacy mechanisms entirely. In commit db3405699f on September 16, 2026, developers deployed four targeted modifications. First, they excised the interpret:// scheme and its companion helper Support::InterpretSendPath from the codebase. Second, socket record delimiters were hardened with percent-hex encoding, preventing multi-command injection. Additionally, two assertions were introduced: skipping CMD: and CTRL: directives if an OPEN: command appears on the same connection, and discarding subsequent local path requests once an external URL is detected.

The subsequent 7.2.9 release incorporated all four patches the next day. However, the release notes only cited general rendering fixes, omitting any security advisory or vulnerability disclosure. The vulnerability had been reported to ZDI on June 25, 2026; the vendor patched it quietly on September 16, and ZDI closed the case as resolved on September 30. beaksec published their independent technical analysis on October 3, and the official CVE was only assigned on October 7. Such silent patching practices obscure critical intelligence needed by enterprise security teams to evaluate client-side threat exposure. At present, CISA’s SSVC decision tree categorizes the exploitation state as “poc”, and it remains unlisted in the Known Exploited Vulnerabilities (KEV) catalog.

Three Defenses to Break the Attack Chain Without Upgrading

While the exploit was demonstrated on Windows version 6.9.3, users unable to immediately upgrade to 7.2.9 or newer can rely on built-in client configuration settings to isolate their installations. Under Advanced Settings, enabling “Ask where to save each file” disrupts the hardcoded path expectations, preventing payload files from landing in predictable locations. Restricting the “Who can add me to group chats” permission to “My Contacts” stops unknown adversaries from pulling victims into hostile channels. Furthermore, users should treat external browser prompts prompting to “Open Telegram” with heightened scrutiny and periodically audit active sessions for suspicious endpoints.

The foundational layer of defense, however, lies in cryptography: configuring a local passcode. The exploit hinges on an empty local passcode, which allows an attacker to compute the encryption keys using default parameters and the stolen salt. Once a local passcode is set, deriving a valid KEK requires the plaintext password. Even if an attacker exfiltrates key_datas and associated files, the payload remains undecryptable without the user’s password. When architectural boundaries fail, uncompromising defensive configurations remain the final barrier against account takeover.

References:

  • Telegram Desktop One-Click Account Takeover Analysis (beaksec)
  • VulnCheck Advisory and Scoring Overview