Back to skill

Security audit

Telegram Bot API

Security checks for vulnerabilities and agentic risk

Overview

This Telegram bot helper is mostly coherent, but it teaches risky token storage and insecure webhook patterns that users should review before installing.

Review before installing. Prefer storing Telegram bot tokens in an environment variable, OS keychain, or secret manager instead of the Markdown memory files. Do not put the bot token in webhook URLs, validate Telegram's secret-token header for every webhook, avoid logging full update payloads, and add explicit consent and retention rules before collecting contacts, locations, or media.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T09 · Insecure Skill Coding Practices

Warning
Location
memory-template.md:27
Finding
Telegram Bot Token Persisted in Plaintext Configuration Files<![CDATA[ ## Vulnerability Details **File Location**: `memory-template.md:27-38`; supporting instructions in `setup.md:18-21` and `setup.md:42-52` **Vulnerability Type**: Plaintext credential storage **Risk Level**: Medium ### Vulnerable Code ```markdown ## Bot Configuration Create `~/telegram-bot-api/bots/{botname}.md`: ```markdown # Bot: {Bot Name} ## Config username: @{username} token: {BOT_TOKEN} created: YYYY-MM-DD ``` ``` The corresponding setup instructions explicitly direct the agent to persist the credential: ```markdown **If they share a token:** 1. Ask permission: "Want me to save this token locally so I can help you test?" 2. If yes, save to `~/telegram-bot-api/bots/{botname}.md` 3. Confirm: "Saved to ~/telegram-bot-api/bots/{name}.md — I won't display it again" ``` ### Technical Analysis A Telegram bot token is a bearer credential. Anyone who obtains it can invoke the Telegram Bot API with the bot's identity and permissions. The Skill instructs the agent to place this credential directly into an ordinary Markdown file. It does not require restrictive file permissions, an encrypted credential store, an operating-system keychain, protection from backup or synchronization systems, or exclusion from source control. Obtaining user consent to save the token does not address the security properties of the storage mechanism. The declaration that the token remains local also does not protect it from other local accounts, malware, indexing services, backup software, accidental repository commits, or other applications operating under the same user account. ### Attack Path 1. The user supplies a valid Telegram bot token and permits the Skill to save it. 2. The Skill creates `~/telegram-bot-api/bots/{botname}.md` containing the plaintext token. 3. The file is exposed through permissive filesystem permissions, a backup, synchronization, indexing, accidental source-control commit, or compromise of the local account. 4. An attacker extracts the token ...[truncated 732 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Store bot tokens in an operating-system keychain or dedicated secret manager rather than Markdown configuration. 2. Keep only a secret reference or environment-variable name in the bot configuration. 3. If file storage is unavoidable: - Create `~/telegram-bot-api/` with mode `0700`. - Create credential files with mode `0600`. - Separate secrets from ordinary preferences and templates. - Avoid placing tokens in files likely to be indexed, synchronized, or committed. 4. Add source-control ignore rules and secret-scanning guidance. 5. Clearly document backup and synchronization risks before saving a token. 6. Provide token rotation instructions using BotFather and require rotation after suspected exposure. 7. Avoid copying the token into generated examples, command history, diagnostic output, or exception messages. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
webhooks.md:198
Finding
Deployable Webhook Examples Accept Unauthenticated Updates<![CDATA[ ## Vulnerability Details **File Location**: `webhooks.md:198-219` and `webhooks.md:229-249` **Vulnerability Type**: Missing webhook authentication **Risk Level**: High ### Vulnerable Code The Flask example processes requests without validating Telegram's secret-token header: ```python from flask import Flask, request import requests app = Flask(__name__) TOKEN = "YOUR_TOKEN" BASE_URL = f"https://api.telegram.org/bot{TOKEN}" @app.route('/webhook', methods=['POST']) def webhook(): update = request.get_json() if 'message' in update: chat_id = update['message']['chat']['id'] text = update['message'].get('text', '') # Echo the message requests.post(f"{BASE_URL}/sendMessage", json={ "chat_id": chat_id, "text": f"You said: {text}" }) return {"ok": True} if __name__ == '__main__': app.run(port=8443, ssl_context=('public.pem', 'private.key')) ``` The Express example has the same issue: ```javascript const express = require('express'); const axios = require('axios'); const app = express(); app.use(express.json()); const TOKEN = 'YOUR_TOKEN'; const BASE_URL = `https://api.telegram.org/bot${TOKEN}`; app.post('/webhook', async (req, res) => { const update = req.body; if (update.message) { const chatId = update.message.chat.id; const text = update.message.text || ''; await axios.post(`${BASE_URL}/sendMessage`, { chat_id: chatId, text: `You said: ${text}` }); } res.json({ ok: true }); }); app.listen(8443); ``` ### Technical Analysis Both primary webhook-server examples trust any JSON body submitted to the public endpoint. They do not validate `X-Telegram-Bot-Api-Secret-Token`, authenticate the source, impose a request-size limit, or apply endpoint-level rate limiting. Although `webhooks.md:136-160` separately demonstrates secret-token verification, the complete Flas ...[truncated 1652 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require a strong, independently generated `secret_token` in every `setWebhook` example. 2. Validate `X-Telegram-Bot-Api-Secret-Token` before parsing or acting on the request body. 3. Load the webhook secret from a secret manager or protected environment variable rather than source code. 4. Reject requests with a missing or incorrect content type, malformed JSON, oversized bodies, or unexpected update structures. 5. Configure explicit request-body size limits and endpoint rate limiting. 6. Return an authorization failure without disclosing whether a particular secret was close or otherwise partially valid. 7. Consider network-layer restrictions as defense in depth, but do not replace secret-token verification with source-IP trust alone. 8. Update both Flask and Express examples so the secure implementation is the default, not an optional separate section. 9. Add tests confirming that missing and incorrect secret headers cannot trigger bot actions. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
webhooks.md:111
Finding
Bot Bearer Credential Embedded in Webhook URL<![CDATA[ ## Vulnerability Details **File Location**: `webhooks.md:111-117` **Vulnerability Type**: Credential disclosure through URL construction **Risk Level**: High ### Vulnerable Code ```bash curl -X POST "https://api.telegram.org/bot${TOKEN}/setWebhook" \ -d "url=https://example.com/webhook/${TOKEN}" \ -d "max_connections=40" \ -d "allowed_updates=[\"message\",\"callback_query\"]" ``` ### Technical Analysis The example embeds the Telegram bot token directly in the webhook URL path. Telegram must send updates to that URL, so the credential is disclosed to the webhook infrastructure in addition to its required use in requests to Telegram. URL paths are routinely captured by reverse-proxy access logs, load balancers, web-server logs, application telemetry, error reports, monitoring services, and infrastructure dashboards. Consequently, the bearer credential can be retained and distributed across systems that do not need it. This behavior conflicts with the Skill's own rule that bot tokens must not be exposed in logs. The webhook path does not need to contain the bot credential because Telegram supports the separate `secret_token` value delivered in the `X-Telegram-Bot-Api-Secret-Token` header. ### Attack Path 1. A developer copies the documented `setWebhook` request. 2. The bot token becomes part of the registered webhook URL. 3. Telegram requests that URL when delivering updates. 4. A reverse proxy, web server, application framework, monitoring platform, or error-reporting system records the request path. 5. An operator, attacker, support user, or compromised logging integration reads the recorded URL. 6. The observer extracts the bot token from the path. 7. The observer uses the token to authenticate directly to the Telegram Bot API. ### Impact Assessment Disclosure permits takeover of the Telegram bot within the permissions granted to it. An attacker may send messages, retrieve available updates, alter webhook settings, change bot configurat ...[truncated 307 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the bot token from the webhook URL. 2. Use a non-secret route such as `https://example.com/webhook` or a random route identifier that is not reused as an API credential. 3. Configure Telegram's independent `secret_token` parameter and validate its request header on every update. 4. Store the bot token and webhook secret separately so disclosure of one does not reveal the other. 5. Ensure reverse proxies and applications redact sensitive query parameters and headers. 6. Rotate any token that has already been placed in a webhook URL. 7. Search proxy, application, monitoring, analytics, and error logs for historical copies of affected URLs and remove them according to incident-response procedures. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
webhooks.md:20
Finding
Complete Telegram Updates and Responses Logged Without Redaction<![CDATA[ ## Vulnerability Details **File Location**: `webhooks.md:20-35`, `webhooks.md:43-66`, and `errors.md:190-195` **Vulnerability Type**: Sensitive information exposure through logging **Risk Level**: Medium ### Vulnerable Code The shell polling example prints every complete update: ```bash #!/bin/bash TOKEN="YOUR_TOKEN" OFFSET=0 while true; do response=$(curl -s "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30") # Process updates echo "$response" | jq -r '.result[] | @json' | while read update; do # Handle each update echo "Received: $update" # Get update_id for offset update_id=$(echo "$update" | jq -r '.update_id') OFFSET=$((update_id + 1)) done done ``` The Python polling example also prints complete update objects: ```python import requests import time TOKEN = "YOUR_TOKEN" BASE_URL = f"https://api.telegram.org/bot{TOKEN}" offset = 0 while True: try: response = requests.get( f"{BASE_URL}/getUpdates", params={"offset": offset, "timeout": 30}, timeout=35 ) updates = response.json().get("result", []) for update in updates: # Process update print(f"Received: {update}") offset = update["update_id"] + 1 except Exception as e: print(f"Error: {e}") time.sleep(5) ``` The debugging guidance further recommends full-response logging: ```markdown ## Debugging Tips 1. **Check `ok` field first** — Even 200 responses can have `ok: false` 2. **Log full responses** — Error details are in `description` 3. **Test with curl** — Isolate issues from your code 4. **Use @BotFather /token** — Regenerate if token exposed 5. **Monitor error patterns** — Track which errors are common ``` ### Technical Analysis Telegram update objects can contain private message text, usernames, stable user and chat identifiers, contact details, locations, media metadata, mem ...[truncated 1745 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove complete-payload printing from default polling examples. 2. Log only minimal operational metadata, such as update type, processing status, and a short non-sensitive correlation identifier. 3. Redact message bodies, names, usernames, chat IDs, user IDs, contact details, location data, callback payloads, payment fields, and URLs before logging. 4. Make payload-level debugging an explicit, temporary opt-in with a clear privacy warning. 5. Apply short retention periods and access controls to all application and platform logs. 6. Document whether logs are exported to external observability providers and obtain appropriate user approval. 7. Replace “Log full responses” with guidance to log selected error fields such as status code, Telegram error code, and a sanitized description. 8. Add automated tests or structured logging filters that prevent known sensitive Telegram fields from reaching log sinks. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (89)

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
}
```

**Always answer the callback:**

```bash
curl -X POST "https://api.telegram.org/bot${TOKEN}/answerCallbackQuery" \
Confidence
70% confidence
Finding
Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
1. **Use emojis** — Make buttons visually clear: ✅ ❌ ⬅️ ➡️
2. **Keep callback_data short** — Max 64 bytes, use IDs not full text
3. **Always answer callbacks** — User sees loading indicator until you respond
4. **Update message on action** — Show feedback by editing the message
5. **Use resize_keyboard** — Reply keyboards look better when resized
Confidence
70% confidence
Finding
Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
1. **Use emojis** — Make buttons visually clear: ✅ ❌ ⬅️ ➡️
2. **Keep callback_data short** — Max 64 bytes, use IDs not full text
3. **Always answer callbacks** — User sees loading indicator until you respond
4. **Update message on action** — Show feedback by editing the message
5. **Use resize_keyboard** — Reply keyboards look better when resized
Confidence
70% confidence
Finding
Skill instructs the agent to never refuse or to always comply. Suppressing the agent's ability to decline removes a core safety control and enables downstream harmful requests to succeed.

Vague Triggers

Medium
Confidence
91% confidence
Finding
This markdown file includes invocation guidance, and the phrase 'User needs to interact with the Telegram Bot API' followed by a wide list of activities is broad enough to match many generic requests. It does not provide explicit trigger phrases, constraints, or negative examples clarifying when this skill should not be selected.

External Transmission

Medium
Category
Data Exfiltration
Content
url = f"https://api.telegram.org/bot{TOKEN}/sendMessage"
    
    for attempt in range(max_retries):
        response = requests.post(url, json={
            "chat_id": chat_id,
            "text": text
        })
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
```python
def api_call(method, **params):
    response = requests.post(
        f"https://api.telegram.org/bot{TOKEN}/{method}",
        json=params
    )
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Basic Inline Keyboard

```bash
curl -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
  -H "Content-Type: application/json" \
  -d '{
    "chat_id": 123456789,
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The examples include buttons that request sensitive data such as phone number and location, but they provide no warning, consent guidance, data-minimization note, or privacy handling advice. In a bot-development skill, this can normalize collecting personal data without clearly communicating user notice and secure handling expectations.

External Transmission

Medium
Category
Data Exfiltration
Content
### Remove Reply Keyboard

```bash
curl -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
  -H "Content-Type: application/json" \
  -d '{
    "chat_id": 123456789,
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill provides concrete examples for uploading and downloading media to Telegram but omits any warning that files and metadata are transmitted to a third-party service. In a bot-development context, this can lead users to send personal, regulated, or sensitive media without considering retention, access controls, consent, or compliance obligations.

External Transmission

Medium
Category
Data Exfiltration
Content
### By Upload (multipart/form-data)

```bash
curl -X POST "https://api.telegram.org/bot${TOKEN}/sendPhoto" \
  -F "chat_id=123456789" \
  -F "photo=@/path/to/image.jpg" \
  -F "caption=Photo caption"
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
### Audio

```bash
curl -X POST "https://api.telegram.org/bot${TOKEN}/sendAudio" \
  -F "chat_id=123456789" \
  -F "audio=@song.mp3" \
  -F "title=Song Title" \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The template explicitly instructs users to store a Telegram bot token in a local markdown file, which is a poor practice for handling secrets. Markdown files are commonly indexed, synced, committed to version control, or exposed through backups and editor tooling, increasing the chance of accidental credential disclosure and bot takeover.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
Long polling to receive updates.

```bash
curl "https://api.telegram.org/bot${TOKEN}/getUpdates?offset=${OFFSET}&timeout=30"
```

| Parameter | Required | Description |
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.