GHSA-6h2f-wjhf-4wjx: Pyrofork has a Path Traversal in download_media Method
SummaryThe `download_media` method in Pyrofork does not sanitize filenames received from Telegram messages before using them in file path construction. This allows a remote attacker to write files to arbitrary locations on the filesystem by sending a specially crafted document with path traversal sequences (e.g., `../`) or absolute paths in the filename.DetailsWhen downloading media, if the user does not specify a custom filename (which is the common/default usage), the method falls back to using the `file_name` attribute from the media object. This attribute originates from Telegram's `DocumentAttributeFilename` and is controlled by the message sender.Vulnerable Code Path**Step 1**: In `pyrogram/methods/messages/download_media.py` (lines 145-151):When a user calls `download_media(message)` or `download_media(message, "downloads/")`, the `os.path.split()` returns an empty filename, causing the code to use `media_file_name` which is attacker-controlled.**Step 2**: In `pyrogram/client.py` (line 1125):The `os.path.join()` function does not prevent path traversal. When `file_name` contains `../` sequences or is an absolute path, it allows writing outside the intended download directory.Why the existing `isabs` check is insufficientThe check at line 153 in `download_media.py`:This check only handles absolute paths by skipping the directory prefix, but:For relative paths with `../`, `os.path.isabs()` returns `False`, so the check doesn't catch itFor absolute paths, `os.path.join()` in the next step will still use the absolute path directlyPoCThe following Python script demonstrates the vulnerability by simulating the exact code logic from `download_media.py` and `client.py`:How to RunSave the above script and run:Expected OutputWhy This Proves the VulnerabilityThe PoC uses the **exact same logic** as the vulnerable code in `download_media.py` and `client.py`The malicious filename `../../../tmp/malicious_file` causes the path to escape from `/tmp/tmpXXX/downloads/` to `/tmp/malicious_file`Python's `os.path.join()` and `os.path.abspath()` behavior is deterministic - this will work the same way in the real libraryImpactWho is affected?Telegram bots or user accounts using Pyrofork that download media with default parametersThe common usage pattern `await client.download_media(message)` is affectedConditions required for exploitationAttacker must be able to send messages to the victim's bot/accountVictim must download the media without specifying a custom filenameThe bot process must have write permissions to the target locationPotential consequences**Arbitrary file write** to locations writable by the bot processOverwriting existing files could cause denial of service or configuration issuesIn specific deployment scenarios, could potentially lead to code execution (e.g., if bot runs with elevated privileges)Recommended FixAdd filename sanitization in `download_media.py` after line 151:This ensures that only the filename component is used, stripping any directory traversal sequences or absolute paths.Thank you for your time in reviewing this report. Please let me know if you need any additional information or clarification.
CVSS v3.1: 6.5