Back to skill

Security audit

Telegram CS Agent

Security checks for vulnerabilities and agentic risk

Overview

This skill builds a real-account Telegram support bot, but it can read and reply to all messages visible to that account and send them to an external AI service without clear scoping or consent.

Install only for a dedicated Telegram account used solely for customer support. Add a deny-by-default chat allowlist, disclose AI and human-support processing to users, validate or remove custom AI base URLs, protect and rotate the Telethon session, use non-echoing secret prompts, and pin dependencies before production use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/telegram_client.py:78
Finding
Account-Wide Telegram Message Interception and External Processing<![CDATA[ ## Vulnerability Details **File Location**: `scripts/telegram_client.py:78-90`, `scripts/main.py:36-76`, `scripts/agent.py:18-54` **Vulnerability Type**: Excessive message-monitoring scope and unauthorized external disclosure **Risk Level**: High ### Vulnerable Code ```python async def listen(self, callback): """Listen for incoming messages, call callback(chat_id, sender_id, text) for each.""" print("[TG] Starting message listener...") @self.client.on(events.NewMessage(incoming=True)) async def handler(event): chat_id = str(event.chat_id) sender_id = str(event.sender_id) text = event.raw_text or "" if text: await callback(chat_id, sender_id, text) await self.client.run_until_disconnected() ``` The captured content is passed to the agent without a chat allowlist: ```python async def on_message(chat_id: str, sender_id: str, text: str): # Skip own messages if sender_id == str(tg.my_id): return # Commands if text.strip().lower() == "/clear": agent.clear_history(chat_id) await tg.send(chat_id, "✅ Conversation history cleared.") return if text.strip().lower() == "/help": await tg.send(chat_id, ( "🤖 Customer Service Bot\n\n" "Ask me anything about our project.\n" "/clear - Clear conversation history\n" "/human - Request human support\n" "/help - Show this message" )) return if text.strip().lower() == "/human": await _handoff(tg, config, chat_id, sender_id, text="User requested human support") await tg.send(chat_id, "🙋 已通知人工客服,稍后会有专人联系您。") return # Agent response print(f"[MSG] {sender_id} in {chat_id}: {text[:80]}") try: await tg.set_typing(chat_id, True) result = agent.chat(chat_id, text) await tg.set_typing(chat_id, False) await tg.send(chat_id, result["reply"]) if resu ...[truncated 3846 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer the Telegram Bot API with a dedicated bot identity instead of authenticating a personal or general-purpose user account. 2. Implement a deny-by-default chat allowlist before passing content to the agent: - Allow only explicitly configured chat IDs. - Distinguish private chats, groups, channels, and service messages. - Reject unknown chats without sending their content externally. 3. Require explicit enrollment or consent before enabling AI processing for a conversation. 4. Add a dry-run or human-approval mode for responses sent from user accounts. 5. Minimize external disclosure: - Send only the current message when history is unnecessary. - Redact identifiers, credentials, wallet secrets, and other sensitive data. - Define retention and deletion limits for in-memory histories. 6. Clearly disclose that messages are processed by an external AI provider. 7. Add automated tests proving that unrelated chats cannot reach `Agent.chat()` or `TelegramClient.send()`. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/config.py:11
Finding
Configurable AI Base URL Can Redirect API Credentials and Conversation Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/config.py:11-14`, `scripts/agent.py:7-14` **Vulnerability Type**: Unvalidated security-sensitive service endpoint **Risk Level**: High ### Vulnerable Code ```python class Config: # Claude anthropic_api_key: str = os.getenv("ANTHROPIC_API_KEY", "") anthropic_base_url: str = os.getenv("ANTHROPIC_BASE_URL", "https://api.anthropic.com") model: str = os.getenv("MODEL", "claude-sonnet-4-20250514") ``` The unvalidated endpoint is supplied directly to the SDK together with the API key: ```python class Agent: def __init__(self, config: Config, kb: KnowledgeBase): self.config = config self.kb = kb self.client = anthropic.Anthropic( api_key=config.anthropic_api_key, base_url=config.anthropic_base_url, ) ``` ### Technical Analysis `ANTHROPIC_BASE_URL` is loaded from the process environment or `.env` file and used without validation. There is no requirement that the URL use HTTPS, no trusted-host allowlist, and no check that the destination is an official Anthropic endpoint. The client is initialized with both the API key and the configurable base URL. Requests sent through this client contain customer messages, retained conversation history, the system prompt, and retrieved knowledge-base context. Depending on SDK authentication behavior, the configured API credential is also transmitted as part of requests to that destination. Environment-driven configuration is not inherently unsafe, but a credential-bearing endpoint is a security boundary. Allowing arbitrary destinations means an attacker who can influence deployment configuration can redirect sensitive traffic without modifying the audited source code. ### Attack Path 1. An attacker gains the ability to alter the deployment environment, service configuration, startup configuration, or project `.env` file. 2. The attacker sets `ANTHROPIC_BASE_URL` to an attacker-controlled ...[truncated 1332 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove runtime configurability when it is unnecessary and pin the endpoint to `https://api.anthropic.com`. 2. If proxy or compatible-provider support is required: - Parse the URL with a standard URL parser. - Require the `https` scheme. - Reject embedded credentials, unexpected ports, fragments, and malformed hosts. - Enforce an explicit allowlist of trusted hostnames. - Resolve redirects carefully and reject redirects to untrusted origins. 3. Use separate API credentials for each approved provider or proxy; never reuse the official provider credential with arbitrary endpoints. 4. Store configuration files with restrictive permissions and protect environment variables through the deployment platform's secret manager. 5. Fail closed when endpoint validation fails. 6. Log only the validated endpoint hostname, never API keys or request bodies. 7. Add startup tests that reject HTTP, localhost, link-local, private-network, metadata-service, and unapproved public destinations. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/telegram_client.py:19
Finding
Telegram Verification Code and 2FA Password Are Entered with Terminal Echo<![CDATA[ ## Vulnerability Details **File Location**: `scripts/telegram_client.py:19-34` **Vulnerability Type**: Plaintext sensitive input exposure **Risk Level**: Medium ### Vulnerable Code ```python async def connect(self): """Connect and verify auth. Auto-login if no session exists.""" await self.client.connect() if not await self.client.is_user_authorized(): print("[TG] No session found. Starting interactive login...") phone = input("Enter your phone number (e.g. +8613800138000): ").strip() await self.client.send_code_request(phone) code = input("Enter the verification code from Telegram: ").strip() try: await self.client.sign_in(phone, code) except Exception: password = input("2FA password required: ").strip() await self.client.sign_in(password=password) print("[TG] Login successful!") self._me = await self.client.get_me() print(f"[TG] Connected as {self._me.first_name} (@{self._me.username}, ID: {self._me.id})") ``` ### Technical Analysis Python's `input()` function echoes typed characters to the terminal. It is suitable for ordinary input but not for authentication secrets. Both the one-time Telegram verification code and the account's 2FA password are collected using `input()`. As a result, these values remain visible while entered and may be captured by screen recordings, terminal-sharing sessions, shoulder surfing, or wrappers that record terminal interaction. The broad `except Exception` block also treats every sign-in failure as a 2FA requirement. This can unnecessarily prompt the operator for a high-value password when the original failure had a different cause. ### Attack Path 1. The bot starts without an authorized Telethon session. 2. The operator begins interactive Telegram authentication. 3. The verification code is entered using an echoing terminal prompt. 4. If `sign_in()` raises any exception, the program requests the Tele ...[truncated 923 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use `getpass.getpass()` for both the verification code and 2FA password: ```python from getpass import getpass code = getpass("Enter the verification code from Telegram: ").strip() password = getpass("2FA password required: ").strip() ``` 2. Catch Telethon's specific 2FA exception, such as `SessionPasswordNeededError`, instead of catching every exception. 3. Do not print, log, persist, or include authentication values in exception messages. 4. Warn operators not to authenticate while screen sharing or recording. 5. Run the authentication step separately from the long-running service and restrict access to the resulting session file. 6. Set restrictive filesystem permissions on the session directory and file. 7. Prefer deployment-time secret provisioning and documented session-rotation procedures. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding
Unpinned Third-Party Dependencies Permit Unreviewed Package Upgrades<![CDATA[ ## Vulnerability Details **File Location**: `scripts/requirements.txt:1-5`, `SKILL.md:30-34` **Vulnerability Type**: Non-reproducible dependency resolution and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```text anthropic>=0.42.0 chromadb>=0.5.0 sentence-transformers>=3.0.0 python-dotenv>=1.0.0 telethon>=1.37.0 ``` The installation instructions are even less constrained: ```bash mkdir -p ~/tg-cs-bot && cd ~/tg-cs-bot cp -r <skill_dir>/scripts/*.py . pip install anthropic chromadb sentence-transformers python-dotenv telethon ``` ### Technical Analysis All declared dependencies use lower-bound constraints rather than exact audited versions, and the documented installation command specifies no versions at all. There is no lockfile, package hash verification, or trusted-index configuration. Consequently, two installations performed at different times can resolve different package versions and transitive dependency trees. Any future release satisfying the lower-bound constraint can be installed automatically without source review or compatibility testing. No evidence was found that the named packages are currently malicious or typosquatted. The vulnerability is the lack of deterministic, integrity-verified dependency resolution in an application that handles high-value Telegram sessions, API credentials, and private messages. ### Attack Path 1. A dependency or transitive dependency publishes a compromised release, or its distribution account is taken over. 2. The compromised version still satisfies the broad `>=` requirement. 3. An operator follows the setup instructions or rebuilds the environment. 4. `pip` resolves and installs the compromised compatible release. 5. Package installation hooks or imported package code execute with the bot process's privileges. 6. Malicious package code reads accessible environment variables, Telegram session files, knowledge documents, or message data. 7. The stolen information can then be t ...[truncated 870 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to an exact reviewed version. 2. Generate a lockfile that includes all transitive dependencies. 3. Require package hashes during installation, for example through a hash-locked requirements file and `pip install --require-hashes`. 4. Update `SKILL.md` to install exclusively from the lockfile rather than installing unconstrained package names. 5. Configure an approved package index or internal artifact mirror. 6. Run dependency vulnerability, provenance, and license scanning in CI. 7. Perform upgrades through an explicit review process with automated tests. 8. Build dependencies in an isolated environment and run the service with a minimally privileged operating-system account. 9. Rebuild and rotate Telegram sessions and API credentials if a compromised dependency is ever detected. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Rogue AgentSelf-Modification, Session Persistence
Findings (24)

Credential Access

High
Category
Privilege Escalation
Content
├── agent.py             # Claude RAG agent
├── knowledge.py         # ChromaDB knowledge base
├── telegram_client.py   # Telethon wrapper
├── .env                 # Secrets (not committed)
├── docs/                # Knowledge base markdown files
│   ├── platform.md
│   ├── faq.md
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Memory Manipulation

High
Category
Memory Poisoning
Content
await tg.send(chat_id, (
                "🤖 Customer Service Bot\n\n"
                "Ask me anything about our project.\n"
                "/clear - Clear conversation history\n"
                "/human - Request human support\n"
                "/help - Show this message"
            ))
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
await tg.send(chat_id, (
                "🤖 Customer Service Bot\n\n"
                "Ask me anything about our project.\n"
                "/clear - Clear conversation history\n"
                "/human - Request human support\n"
                "/help - Show this message"
            ))
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill instructs the user to create files, install packages, copy scripts, and run Python code, but it declares no tool scope or permission boundaries. In an agent ecosystem, this can cause the skill to be invoked with broader-than-expected access to shell, files, and environment secrets, increasing the chance of unintended execution or data exposure.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases include broad terms like "telegram bot" and "knowledge base," which are common across many unrelated tasks. Overbroad activation can cause the wrong skill to run in inappropriate contexts, leading to accidental handling of credentials, shell actions, or deployment steps when the user did not intend to invoke this skill.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill describes using a Telethon userbot that logs in as a real user account, but it does not prominently warn about the security, privacy, and policy risks of handling Telegram API credentials and persistent user sessions. Because the bot impersonates a real account rather than using the Bot API, compromise or misuse could expose private messages, contacts, account metadata, and enable unauthorized messaging.

Session Persistence

Medium
Category
Rogue Agent
Content
## Setup New Bot

### 1. Create project

```bash
mkdir -p ~/tg-cs-bot && cd ~/tg-cs-bot
Confidence
78% confidence
Finding
The setup and login flow creates a persistent Telethon session on disk for a real Telegram account, and the skill does not specify storage protections, rotation, or cleanup. Persistent sessions materially increase risk because anyone with access to the session file can often reuse it to access the account without re-authenticating.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
This markdown content appears to force a specific language experience without offering an opt-in, alternative locale, or stating that the skill is intentionally region/language-specific. Under the policy, language-only content can be a natural-language policy violation when no user choice or justification is provided.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
This document gives detailed operational guidance for ultra-short-term binary-style crypto trading, including bet sizing, payout mechanics, settlement timing, and price-source behavior, but it does not provide any explicit risk warning, responsible-use notice, or loss disclaimer beyond describing that a user can lose the stake. In the context of a customer-service bot knowledge base, this can cause the agent to present speculative trading as routine and frictionless, increasing the chance of facilitating harmful financial behavior without appropriate caution.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The guide instructs users to connect wallets, create events, post deposits, and trade positions where losses can reduce holdings to zero, but it does not provide any warning about financial risk, irreversible blockchain transactions, wallet security, or the need to verify addresses and network details. In the context of an agent skill that may operationalize setup and knowledge-base content for a Telegram bot, this omission could cause users to act on high-risk financial instructions without informed consent or basic safety precautions.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The code sends both user messages and retrieved knowledge-base context to Anthropic via an external API call, but this file shows no consent flow, minimization, or redaction before transmission. In a customer-service bot context, chats and KB snippets may contain personal, confidential, or proprietary data, so undisclosed third-party transfer creates a real privacy and data-governance risk.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The bot sends user-facing messages in Chinese at L59 and L72, while other help and error messages are in English. This imposes a language choice on users without opt-in or documented justification, which is a natural-language locale policy issue.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The handoff flow forwards user identifiers and message content to a separate handoff chat, but the bot does not clearly warn users that their conversation details will be shared with human operators. This creates a privacy and data-handling risk, especially because users may disclose sensitive information assuming they are speaking only to the bot.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This code prompts the user to enter a phone number, Telegram verification code, and potentially a 2FA password, which are sensitive authentication inputs. While the login flow is expected, there is no disclosure about credential handling, storage implications of the session, or caution around entering sensitive data into the skill.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
All user-facing instructions in the file are written in Chinese, and there is no indication that users may choose another language or that the skill is intentionally restricted to a Chinese-speaking audience. The policy requires flagging language or locale constraints when they are imposed without user opt-in or clear justification.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The title explicitly labels this as an English user guide, and the file contains no language-choice or opt-in language. Under the policy rule for locale constraints, this is a natural-language policy concern unless the English-only scope is justified or users are offered alternatives.

Unpinned Dependencies

Low
Category
Supply Chain
Content
anthropic>=0.42.0
chromadb>=0.5.0
sentence-transformers>=3.0.0
python-dotenv>=1.0.0
Confidence
96% confidence
Finding
The dependency is specified with only a lower bound, so future installs may resolve to different upstream releases, including buggy or malicious versions introduced after review. In a bot stack that handles API keys, knowledge-base data, and network connectivity, this weakens supply-chain integrity and makes builds non-reproducible.

Unverifiable Dependency: anthropic has 4 known advisory(ies) (CVE-2026-34450 (Claude SDK for Python has Insecure Default File Permissions in Local Filesystem ); CVE-2026-34452 (Claude SDK for Python: Memory Tool Path Validation Race Condition Allows Sandbox); CVE-2026-34450 (The Claude SDK for Python provides access to the Claude API from Python applicat) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding
The manifest does not pin anthropic, so there is no way to verify whether deployment will use a release affected by known advisories. In this skill context, the SDK may process prompts, files, or local data while holding API credentials, so uncertain version selection meaningfully increases risk.

Unpinned Dependencies

Low
Category
Supply Chain
Content
anthropic>=0.42.0
chromadb>=0.5.0
sentence-transformers>=3.0.0
python-dotenv>=1.0.0
telethon>=1.37.0
Confidence
97% confidence
Finding
ChromaDB is a complex data and service dependency, and using an unpinned version allows unnoticed adoption of releases with new vulnerabilities or breaking security behavior. Because this skill uses RAG and a knowledge base, dependency drift here could directly affect confidentiality or integrity of stored documents and bot behavior.

Unverifiable Dependency: chromadb has 8 known advisory(ies) (CVE-2026-45830 (ChromaDB allows any authenticated users to arbitrarily read, write, update, or d); CVE-2026-45833 (ChromaDB has a code injection vulnerability); CVE-2026-45829 (ChromaDB Python project has a pre-authentication code injection vulnerability) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
96% confidence
Finding
ChromaDB has multiple known advisories and the requirement is not pinned, so installs may resolve to a vulnerable release without visibility. Given this bot stores and retrieves customer-service knowledge-base data, a vulnerable vector database could expose or corrupt indexed content and materially affect bot responses.

Unpinned Dependencies

Low
Category
Supply Chain
Content
anthropic>=0.42.0
chromadb>=0.5.0
sentence-transformers>=3.0.0
python-dotenv>=1.0.0
telethon>=1.37.0
Confidence
93% confidence
Finding
An unpinned sentence-transformers dependency creates non-reproducible builds and increases exposure to upstream package compromise or vulnerable transitive updates. While not inherently dangerous by itself, it broadens the software supply-chain attack surface for the bot deployment.

Unpinned Dependencies

Low
Category
Supply Chain
Content
anthropic>=0.42.0
chromadb>=0.5.0
sentence-transformers>=3.0.0
python-dotenv>=1.0.0
telethon>=1.37.0
Confidence
95% confidence
Finding
python-dotenv often interacts with environment files containing secrets, and leaving the version unpinned can silently introduce vulnerable behavior into secret-loading workflows. This is especially relevant in a bot deployment that likely stores API tokens and service credentials in environment variables.

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
92% confidence
Finding
The unpinned python-dotenv dependency makes it impossible to confirm whether deployed versions include known file-handling flaws. Because .env files often contain secrets for Telegram and model APIs, vulnerable behavior here could lead to credential exposure or unsafe file modification in deployment environments.

Unpinned Dependencies

Low
Category
Supply Chain
Content
chromadb>=0.5.0
sentence-transformers>=3.0.0
python-dotenv>=1.0.0
telethon>=1.37.0
Confidence
94% confidence
Finding
telethon is network-facing and handles Telegram sessions and credentials, so unpinned installs can pull in unexpected versions with security regressions or malicious supply-chain changes. The lack of deterministic versioning reduces confidence in the bot's runtime security posture.

Static analysis

No suspicious patterns detected.