Back to skill

Security audit

Telegram Readonly

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent read-only Telegram skill, but it relies on mutable remote install code and stores a powerful reusable Telegram login locally.

Review and pin the CLI source before installing, preferably to a specific audited commit or signed release. Treat TELEGRAM_API_ID, TELEGRAM_API_HASH, and ~/.config/telegram-readonly/config.json as secrets; do not commit, log, paste, or expose them to other tools. Use the skill only for narrow read tasks, and know how to revoke the Telegram session if the config file or session string may have been exposed.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:27
Finding
Unpinned Executable Dependency Installed from a Mutable Git Repository## Vulnerability Details **File Location**: `SKILL.md:27` **Vulnerability Type**: Supply-chain risk from an unpinned remote dependency **Risk Level**: Medium ### Vulnerable Code ```bash pipx install git+https://github.com/ropl-btc/telegram-readonly-cli.git ``` The same unsafe installation approach is also documented in `references/setup-and-safety.md:36-43`, including installation from the repository's mutable default branch. ### Technical Analysis The recommended installation command retrieves and installs executable Python package content directly from an unpinned Git repository. It does not specify an immutable commit hash, a verified signed release, or a package hash. Consequently, the code installed by this command can change after the Skill has been audited. Package installation may execute build-system or installation logic supplied by the remote repository. This creates a supply-chain boundary between the reviewed Skill and the executable CLI users are instructed to trust. This risk is especially significant because the installed CLI is subsequently given access to Telegram API credentials, login codes, a 2FA password, a reusable Telethon `StringSession`, and personal Telegram content. No evidence establishes that the current upstream repository is malicious. The vulnerability is that the documented installation process provides no immutable version or integrity guarantee. ### Attack Path 1. An attacker compromises the upstream repository, a maintainer account, or the repository ownership. 2. The attacker modifies package installation logic or runtime code on the default branch. 3. A user follows the documented `pipx install git+https://...` instruction. 4. `pipx` retrieves and installs the attacker's modified code. 5. The malicious package executes during installation or when the Telegram CLI is invoked. 6. It captures Telegram credentials, authentication inputs, the stored session string, or message con ...[truncated 639 chars]
Remediation
## Remediation Suggestions - Pin the Git dependency to a reviewed, immutable full commit hash. - Prefer a versioned package distributed through a trusted registry with published integrity hashes. - Use signed releases and verify the signature before installation. - Record the expected source revision and package hashes in the Skill documentation. - Audit package metadata and build-system configuration in addition to runtime source code. - Avoid automatic upgrades from a mutable branch. - Run installation and authentication in a minimally privileged, isolated environment. - Update both `SKILL.md` and `references/setup-and-safety.md` so all installation methods use the same verified version.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/telegram_readonly.py:35
Finding
High-Privilege Telegram Session Written Before Restrictive Permissions Are Applied## Vulnerability Details **File Location**: `scripts/telegram_readonly.py:35-39` **Vulnerability Type**: Non-atomic creation of a plaintext credential file **Risk Level**: Low ### Vulnerable Code ```python def save_config(data: dict[str, Any]) -> None: CONFIG_DIR.mkdir(parents=True, exist_ok=True) CONFIG_PATH.write_text(json.dumps(data, indent=2) + "\n") chmod_600(CONFIG_PATH) ``` ### Technical Analysis `Path.write_text()` creates or truncates the configuration file using permissions derived from the process umask. The code changes the file to mode `0600` only after all sensitive data has been written. The configuration contains the Telegram API ID, API hash, and reusable Telethon `StringSession`. With an unusually permissive umask or unsuitable pre-existing directory permissions, another local user may be able to read the newly created file during the interval before `chmod_600()` runs. The operation is also non-atomic. Process termination, filesystem failure, or interruption between writing and permission hardening can leave a credential file with unintended permissions or incomplete content. The code does not explicitly create the configuration directory with mode `0700`, validate ownership, or reject an unsafe pre-existing path. ### Attack Path 1. The attacker has access to another local account on the same system and can traverse or monitor the configuration directory. 2. The victim runs the `auth` command, causing `save_config()` to create or rewrite `~/.config/telegram-readonly/config.json`. 3. A permissive umask causes the file to be initially created with permissions broader than `0600`. 4. The attacker monitors the path and reads the file after `write_text()` creates it but before `chmod_600()` completes. 5. The attacker extracts the reusable `session_string` and associated API credentials. 6. The attacker loads the session into a compatible Telethon client and attempts to access the victim' ...[truncated 713 chars]
Remediation
## Remediation Suggestions - Create `~/.config/telegram-readonly` with mode `0700` and verify that it is owned by the current user. - Create a temporary file atomically with mode `0600`, such as through `os.open()` using `O_CREAT | O_EXCL` and an explicit mode of `0o600`. - Write and flush the serialized configuration to the protected temporary file. - Call `fsync()` where durability is required, then atomically replace the destination with `os.replace()`. - Reject symbolic links and validate the ownership and type of any pre-existing destination. - Apply restrictive permissions before writing any credential bytes rather than correcting permissions afterward. - Consider storing the session in an operating-system credential manager or encrypted secret store instead of a plaintext JSON file. - Document session-revocation procedures so users can terminate a potentially exposed Telegram session promptly.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Env Variable Harvesting

High
Category
Data Exfiltration
Content
if q in title:
        score += 40
    score += sum(8 for token in tokens if token in username)
    score += sum(6 for token in tokens if token in name)
    score += sum(5 for token in tokens if token in title)
    score += min(len(tokens), 5)
    return score
Confidence
80% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill invokes shell commands, reads environment variables for Telegram API credentials, and references config/session files, but it declares no explicit tool scope or permissions boundary. In an agent setting, that increases the risk of overbroad access and makes it harder to enforce least privilege for a workflow that handles highly sensitive account data.

Session Persistence

Medium
Category
Rogue Agent
Content
---
name: telegram-readonly
description: Read the user's personal Telegram account in a controlled, read-only way via Telethon/MTProto. Use when you need to inspect Telegram chats, list dialogs, read recent messages from a specific chat, or search Telegram messages without relying on the Telegram Bot API. Do not use for sending, replying, editing, deleting, or any write action.
---

# Telegram Readonly
Confidence
78% confidence
Finding
The skill requires authentication and stores session/config state under the user's home directory, creating persistent access to a personal Telegram account beyond a single invocation. Even though persistence is operationally necessary for Telethon, it is still a security concern because compromise of the session data could allow unauthorized ongoing account access.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The skill mentions treating the Telethon session as a high-privilege secret, but it does not present a clear user-facing warning near setup and usage that API credentials and session files can grant persistent access to a personal Telegram account. Because this skill targets a real personal account, insufficient warning materially raises the chance of unsafe handling, accidental disclosure, or misuse of persisted secrets.

Session Persistence

Medium
Category
Rogue Agent
Content
1. Telegram API credentials from `https://my.telegram.org`
2. Telethon installed through the package
3. One interactive login to create a session string

## Install
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Static analysis

No suspicious patterns detected.