T09 · Insecure Skill Coding Practices
- Location
scripts/setup.py:17- Finding
Insecure Handling of Telegram OTP and 2FA Credentials
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill does what it says, but it takes broad control of a Telegram account and handles private messages and login secrets in ways users should review carefully.
Install only if you are comfortable giving this skill a reusable Telegram session that can read private chats and send messages as you. Use a dedicated or low-risk Telegram account, tightly limit the contact whitelist, avoid command-line or plaintext-file 2FA handling, protect config.json and .session files, disable owner notifications unless needed, and review each paid-media action before running it.
scripts/setup.py:17Insecure Handling of Telegram OTP and 2FA Credentials
scripts/autopilot.py:24Private Telegram Conversations Stored in Plaintext
scripts/autopilot.py:67Prompt Injection Can Override Autopilot Persona and Reply Constraints
scripts/autopilot.py:37Unescaped Telegram HTML in Owner Notifications
The skill explicitly supports forwarding every incoming message and generated reply to an owner-controlled bot/chat. That creates a built-in exfiltration path for private Telegram communications, and if the bot token or owner chat is misconfigured or compromised, sensitive conversations can be leaked without the correspondents' knowledge.
- **Never commit** `config.json` (contains API keys) or `.session` files
- **OTP server** binds to `127.0.0.1` only — never expose it to the network
- **Transparency:** If someone directly asks if they're talking to AI, the bot is honest
- **Notifications** forward messages to the owner — ensure you control the bot token
- Telegram may restrict accounts with aggressive automation — natural delays are built in
- Only one process can use a session file at a time
- Using a userbot may violate Telegram ToS — use at your own risk
The skill claims to manage AI auto-replies, but the documented capabilities also include channel-based paid media posting and invite-link distribution, which are outside the narrow expectation of message autopilot behavior. This mismatch broadens the operational scope toward account actions and monetization flows that could surprise users and increase abuse potential if invoked unintentionally.
The skill claims to manage AI auto-replies, but the documented capabilities also include channel-based paid media posting and invite-link distribution, which are outside the narrow expectation of message autopilot behavior. This mismatch broadens the operational scope toward account actions and monetization flows that could surprise users and increase abuse potential if invoked unintentionally.
The skill can send messages and media as the user and conceal that responses are automated, yet the opening description does not prominently warn about impersonation and autonomous account actions. That omission increases the likelihood of uninformed consent and unsafe use in sensitive personal conversations.
The documented ability to forward messages to the owner via bot is an explicit exfiltration path for private Telegram content. In the context of a personal-account autopilot, this is especially sensitive because the skill operates on direct messages and can silently relay conversations outside the participants' expectations.
- **Session security:** The `.session` file grants full access to the account. Protect it like a password.
- **Transparency:** The AI is instructed to be honest if directly asked whether it's AI.
- **OTP server:** `code_server.py` binds to `127.0.0.1` (localhost only). Never expose it to the network.
- **Notifications:** The skill can forward messages to the owner via bot. Ensure you control the bot token and chat_id.
- **Rate limits:** Telegram may restrict accounts with aggressive automation. The autopilot uses natural delays.
- **One session at a time:** Only one process can use a session file. Stop autopilot before running other scripts.
- **Platform policies:** Using a userbot to auto-reply may violate Telegram ToS. Use at your own risk.
The function builds prompts that include up to 10 prior conversation entries and then submits them to an external model provider, causing cumulative disclosure of private conversations. This increases exposure beyond the latest message and can leak sensitive historic context, personal data, or confidential discussions to third-party AI services.
The code copies incoming private messages into a separate owner notification channel using a bot, disclosing message contents beyond the original one-to-one chat. This creates a confidentiality breach because sensitive messages from contacts are duplicated to another chat and also exposed to Telegram Bot API processing.
The workflow is explicitly designed to read authentication factors from predictable files (enter_code.txt and enter_password.txt) in a user-supplied working directory. This constitutes credential materialization on disk, which expands the attack surface through local file disclosure, accidental backup/sync, race conditions, or misuse of an insecure/shared workdir. In this skill’s context, the secrets grant access to a Telegram account that will act as the user, making the exposure more dangerous than a generic temporary token leak.
async def main(args):
session_path = os.path.join(args.workdir, args.session)
code_file = os.path.join(args.workdir, "enter_code.txt")
pw_file = os.path.join(args.workdir, "enter_password.txt")
for f in (code_file, pw_file):
if os.path.exists(f):
The script prints the one-time login code directly to stdout with GOT_CODE: {code}. OTPs are authentication secrets, and stdout is commonly captured by terminals, logs, orchestration tools, agent transcripts, or monitoring systems, so this unnecessarily exposes a live credential that can be reused during the login window. In the context of a Telegram userbot that authenticates as the user, leakage can enable full account takeover during setup.
The script accepts the Telegram 2FA password via a command-line argument or plaintext file polling. Command-line arguments may be visible to other local users through process listings and shell history, and plaintext files in a shared or weakly permissioned working directory can be read by other processes or retained after use. Because this skill manages a personal Telegram account, compromise of the 2FA password materially increases the risk of account takeover.
The README describes AI auto-replies and provider configuration, but it does not clearly warn that private Telegram message contents and conversation context are sent to external AI providers for processing. In a personal messaging autopilot, that omission is security-relevant because users may unknowingly expose sensitive conversations, contacts, and metadata to third parties.
The skill declares no explicit tool scope even though it clearly instructs network access and local file writes. In an agent environment, missing scope boundaries can cause the skill to be invoked with broader-than-expected capabilities, increasing the chance of unintended credential handling, file modification, or network activity.
Trigger phrases like 'manage my telegram' and 'respond for me' are broad enough to match ordinary user requests that may not imply consent to impersonation, account automation, or credential use. In an agent system, overly broad routing can activate a high-impact skill in the wrong context and lead to unintended message sending or secret collection.
Forwarding incoming private messages and sent replies to an owner-controlled bot creates a secondary disclosure channel for personal chat content. Even if intended for monitoring, this duplicates sensitive communications outside the original chat context and can expose correspondents' data, secrets, and private conversations.
Storing the Telegram API credentials, phone-related login context, AI API key, and optional bot token together in a plain config.json centralizes multiple high-value secrets in one file. Compromise of that file can enable account takeover, AI API abuse, and monitoring-channel abuse all at once, increasing blast radius significantly.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
chat_id = notif.get("chat_id")
if not token or not chat_id:
return
url = f"https://api.telegram.org/bot{token}/sendMessage"
data = json.dumps({"chat_id": chat_id, "text": text, "parse_mode": "HTML"}).encode()
req = urllib.request.Request(url, data=data, headers={"Content-Type": "application/json"})
try:
The code selects a language from contact configuration and instructs the model to reply in that language, which imposes a locale choice on the conversation without any visible user choice or opt-in mechanism. This matches the policy concern for language or locale constraints that are forced rather than offered.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
"messages": messages,
}).encode()
req = urllib.request.Request(
"https://api.anthropic.com/v1/messages",
data=payload,
headers={
"Content-Type": "application/json",
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
headers = {"Content-Type": "application/json"}
if ai.get("api_key"):
headers["Authorization"] = f"Bearer {ai['api_key']}"
req = urllib.request.Request(ai.get("base_url", "https://api.openai.com/v1/chat/completions"), data=payload, headers=headers)
with urllib.request.urlopen(req, timeout=30) as resp:
result = json.loads(resp.read())
return result["choices"][0]["message"]["content"].strip()
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
headers = {"Content-Type": "application/json"}
if ai.get("api_key"):
headers["Authorization"] = f"Bearer {ai['api_key']}"
req = urllib.request.Request(ai.get("base_url", "https://api.openai.com/v1/chat/completions"), data=payload, headers=headers)
with urllib.request.urlopen(req, timeout=30) as resp:
result = json.loads(resp.read())
return result["choices"][0]["message"]["content"].strip()
The handler forwards private message content to an external AI provider to generate a reply, but this file contains no explicit user-facing consent, notice, or minimization before transmitting third-party message data off-platform. In a Telegram userbot context, this is a real privacy/security issue because private correspondents may not expect their messages to be sent to Anthropic/OpenAI-compatible services.
The generated reply is copied to the notification channel, leaking derivative conversation content to an additional destination outside the original chat. While this may be intended for monitoring, it still expands access to potentially sensitive communications and can reveal inferred private details from the exchange.
The OTP code is persisted to a plaintext file on disk, which unnecessarily extends the lifetime of a highly sensitive authentication secret beyond the login flow. On a multi-user system, shared workspace, synced folder, or compromised host, another process or user could read the file and use the code during the valid window, and the page also reflects the code back in the response, increasing accidental disclosure risk.
This script performs actions outside the advertised autopilot scope by creating a private Telegram channel, posting paid media, exporting an invite link, and sending that link to another user. In a skill that already requires full Telegram user credentials, this scope expansion increases the chance of unauthorized account actions and deceptive or unintended outreach as the user.
The script performs irreversible or externally visible actions—creating a channel, posting media, exporting an invite, and messaging a target—without any confirmation step or warning. In the context of a Telegram userbot with account-level access, this makes accidental misuse, social engineering, or abuse through automation materially more dangerous.
No suspicious patterns detected.