|
| 1 | +# Threat model |
| 2 | + |
| 3 | +## What Telegram Desktop is and where untrusted input enters |
| 4 | + |
| 5 | +Telegram Desktop is the official desktop client for Telegram, written in C++20 with Qt 6, for Windows, macOS and |
| 6 | +Linux. It speaks MTProto 2.0 to Telegram's servers itself (`Telegram/SourceFiles/mtproto/`), keeps an encrypted local |
| 7 | +cache (`Telegram/SourceFiles/storage/`), and renders everything that users, bots and channels send. The desktop-app |
| 8 | +libraries are submodules under `Telegram/lib_*` (UI and text layout in `lib_ui`, Lottie in `lib_lottie`, TL |
| 9 | +serialization in `lib_tl`, webviews in `lib_webview`, call glue in `lib_webrtc`, and more). They are part of this |
| 10 | +project and in scope. Paths below are relative to `Telegram/SourceFiles/` unless they start with `Telegram/`. |
| 11 | + |
| 12 | +The main attacker is any other Telegram user, bot or channel. Anyone can message the victim, add them to a group or |
| 13 | +post in a channel they read. Everything such a party controls is untrusted, even though it arrives from Telegram's |
| 14 | +servers over an authenticated MTProto session: |
| 15 | + |
| 16 | +* message text, entities and formatting (`api/api_text_entities.cpp`, `Telegram/lib_ui/ui/text/`), rich messages and |
| 17 | + Instant View pages, including markdown and formulas (`iv/`, `iv/markdown/`); |
| 18 | +* names, usernames, bios, file names, captions, polls, contacts, locations, reply and inline keyboards, inline bot |
| 19 | + results (`inline_bots/`), and link previews (`data/data_web_page.cpp`); |
| 20 | +* media: photos, videos, GIFs, voice and video messages, documents, stickers in every format (Lottie TGS through |
| 21 | + `lib_lottie`, WebM, WebP), custom emoji, wallpapers and patterns, themes (`window/themes/`), and cloud language |
| 22 | + packs (`lang/`). Much of this is downloaded and decoded automatically, without a click (`media/`, `ffmpeg/`, |
| 23 | + `history/view/media/`); |
| 24 | +* links: `tg://` and `t.me` links handled in `core/local_url_handlers.cpp`, including proxy links that change |
| 25 | + network settings; |
| 26 | +* bot Mini Apps, payment forms and Instant View webviews. They load web pages written by arbitrary bot or site |
| 27 | + owners, which talk to the client through the JavaScript bridge in `ui/chat/attach/attach_bot_webview.cpp`, |
| 28 | + `inline_bots/bot_attach_web_view.cpp`, `iv/` and `Telegram/lib_webview`; |
| 29 | +* calls and group calls (`calls/`, `tde2e/`, `Telegram/ThirdParty/tgcalls`): the other party's signaling and media; |
| 30 | +* received files that the user saves or opens: `core/file_utilities.cpp`, `data/data_document_resolver.cpp`, and |
| 31 | + `core/mime_type.cpp` (`Core::DetectNameType`, which decides when to warn that a file may be dangerous to open). |
| 32 | + |
| 33 | +The second attacker is on the network: a malicious MTProxy, SOCKS5 or HTTP proxy, or anyone on the path. It sees |
| 34 | +only MTProto ciphertext but controls everything before decryption: the transports and the fake-TLS handshake |
| 35 | +(`mtproto/connection_*.cpp`, `mtproto/details/mtproto_tls_socket.cpp`, `mtproto/details/mtproto_tcp_socket.cpp`), |
| 36 | +auth key creation and server RSA key checks (`mtproto/details/mtproto_dc_key_creator.cpp`, |
| 37 | +`mtproto/details/mtproto_rsa_public_key.cpp`), and decryption and integrity checks of incoming packets |
| 38 | +(`mtproto/session_private.cpp`). |
| 39 | + |
| 40 | +The third is the update channel. `core/update_checker.cpp`, `core/update_verify.cpp` and `core/update_unpack.cpp` |
| 41 | +download, verify and unpack signed update packages. |
| 42 | + |
| 43 | +Lower priority: other local programs that talk to the single-instance socket in `core/sandbox.cpp` or start the app |
| 44 | +with a `tg://` link on the command line, and attacker content written into Export Chat History output (`export/`), |
| 45 | +which the user later opens in a browser. |
| 46 | + |
| 47 | +We treat Telegram's servers as honest relays. Data that only the server controls (configuration, data center |
| 48 | +options, fields no other user can set) is less important than data another user controls, and a report that needs a |
| 49 | +malicious Telegram server should say so. The local user, the operating system and the files in the user's profile |
| 50 | +are trusted. |
| 51 | + |
| 52 | +## Components that matter most and least |
| 53 | + |
| 54 | +Most important: |
| 55 | + |
| 56 | +* `mtproto/`: everything before and around decryption, and session state; |
| 57 | +* `api/`, `data/`, `history/`: turning server updates into client objects, and rendering messages; |
| 58 | +* `media/`, `ffmpeg/`, `Telegram/lib_lottie`, `Telegram/lib_ui` (text layout, images, emoji): decoding and |
| 59 | + drawing attacker-supplied content; |
| 60 | +* `iv/`, `inline_bots/`, `ui/chat/attach/`, `payments/`, `Telegram/lib_webview`: webviews and their bridges to |
| 61 | + native code; |
| 62 | +* `core/` (link handlers, file opening, the updater), `window/themes/`, `lang/`; |
| 63 | +* `storage/` (local encrypted storage and serialization), `passport/` (Telegram Passport decryption), `calls/`, |
| 64 | + `tde2e/`, `webauthn/` (passkeys, including the caBLE tunnel). |
| 65 | + |
| 66 | +Lower priority: settings, boxes and other UI layout code, `info/`, `statistics/`, `intro/`, `export/`. Code in |
| 67 | +`platform/win/` and `platform/mac/` is in scope for review, but it isn't built in this Linux image. |
| 68 | + |
| 69 | +Out of scope: |
| 70 | + |
| 71 | +* the libraries prebuilt in the base image (Qt, FFmpeg, OpenSSL, WebRTC, OpenAL and others), except where |
| 72 | + Telegram Desktop misuses them; |
| 73 | +* vendored code in `Telegram/ThirdParty/`, unless content from Telegram reaches the bug. Then name the upstream |
| 74 | + project; |
| 75 | +* `Telegram/SourceFiles/test/` and anything else under `#ifdef _DEBUG`. This image is a Debug build, but that code |
| 76 | + is not in release builds; |
| 77 | +* `Telegram/build/`, `docs/`, and `Telegram/SourceFiles/tests/`. |
| 78 | + |
| 79 | +## How to exercise it |
| 80 | + |
| 81 | +* `/src/out/Debug/Telegram` is built with `-O0 -g` and AddressSanitizer. The image sets |
| 82 | + `ASAN_OPTIONS=detect_leaks=0`. The build tree uses Ninja Multi-Config: |
| 83 | + `cmake --build /src/out --config Debug --target Telegram` rebuilds incrementally, and |
| 84 | + `/src/out/compile_commands.json` has the exact flags for every source file. |
| 85 | +* The app needs a display and Telegram's servers, and the scan has neither. The practical way to reproduce a bug is |
| 86 | + a small harness that feeds the crafted input to the function in question. Build it with the flags from |
| 87 | + `compile_commands.json` and link it against the static libraries in `/src/out` (`find /src/out -name '*.a'`). |
| 88 | + The generated TL (de)serialization code is under `/src/out` too (`find /src/out -name 'scheme*'`). |
| 89 | +* `out/Debug/test_update_verify` and `out/Debug/test_update_unpack` are standalone harnesses of this kind. Their |
| 90 | + sources are in `Telegram/SourceFiles/tests/` and their CMake in `Telegram/cmake/test_update_*.cmake`. |
| 91 | +* For received content, show the TL object (constructor and fields) another user can get delivered, and say whether |
| 92 | + the server is likely to relay it unchanged. Entity offsets, file names and sizes may be validated server-side. For |
| 93 | + network issues, show the bytes the proxy or network attacker sends. |
| 94 | + |
| 95 | +## How we rate severity |
| 96 | + |
| 97 | +* Critical: code execution or memory corruption from content another user, bot or channel sends, with no |
| 98 | + interaction beyond receiving it or opening the chat (auto-downloaded media, sticker, emoji and link preview |
| 99 | + rendering). Getting an attacker's file executed without the dangerous-file warning. Bypassing update signature |
| 100 | + verification. Reading or forging MTProto traffic, or obtaining the auth key, as a proxy or network attacker. |
| 101 | + Remotely reading local files or session keys. |
| 102 | +* High: memory corruption that needs one ordinary action, such as opening a file, playing media, or opening an Instant |
| 103 | + View page, a Mini App or a link. A Mini App or web page reaching native features without the confirmation the user |
| 104 | + normally sees: sending messages, sharing the phone number, reading local files, or opening other URL schemes. |
| 105 | + Writing outside the chosen folder through an attacker-chosen file name. Out-of-bounds reads that send memory |
| 106 | + contents back to the attacker. A received message that crashes the client on every launch. |
| 107 | +* Medium: crashes from received content that go away after a restart (null dereference, uncaught exception, or a |
| 108 | + failed `Assert`, `Expects` or `Unexpected`, which stay fatal in release builds). Leaking the user's IP address to a |
| 109 | + third party without a click or around the configured proxy. UI spoofing that hides a link's real target or a |
| 110 | + file's real extension. |
| 111 | +* Low: resource exhaustion without a crash. Script injection into Export Chat History output. Issues that need a |
| 112 | + malicious Telegram server rank one level below the same issue from a field another user controls. |
| 113 | + |
| 114 | +A buffer overflow, use-after-free or double free reachable from received content is High at least, even without a |
| 115 | +demonstrated exploit. |
| 116 | + |
| 117 | +## Anything to leave alone |
| 118 | + |
| 119 | +* Memory leaks. LeakSanitizer is off on purpose. |
| 120 | +* `api_id` and `api_hash` values in the source, which are public by design (`docs/api_credentials.md`). |
| 121 | +* Attacks by someone who already has the user's local account or files, including reading the profile folder of an |
| 122 | + account without a local passcode. |
| 123 | +* Bugs in the prebuilt libraries listed above, unless Telegram Desktop's use of them is the problem. |
0 commit comments