Back to skill

Security audit

Telegram Whisper Transcribe

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it creates a persistent Telegram bot that can let any reachable Telegram user spend the owner’s OpenAI credits unless the operator adds access controls.

Review before installing. Use a dedicated OpenAI key with spending limits, add a Telegram user/chat allowlist and rate limits before exposing the bot, avoid passing real secrets on the command line, and treat ~/transcribe-bot/.env as sensitive. Users sending audio should understand it is uploaded to OpenAI for transcription.

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 (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/bot.py:91
Finding
Unrestricted Bot Access Permits Abuse of the Owner's Paid OpenAI API<![CDATA[ ## Vulnerability Details **File Location**: `scripts/bot.py:31-59` and `scripts/bot.py:91-93` **Vulnerability Type**: Missing authorization and resource-consumption controls **Risk Level**: High ### Vulnerable Code ```python async def handle_voice(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: """Sprachnachricht oder Audio transkribieren.""" msg = update.message audio = msg.voice or msg.audio or msg.video_note if not audio: return log.info("Audio empfangen von %s (%d bytes)", msg.from_user.first_name, audio.file_size or 0) try: # Datei von Telegram herunterladen tg_file = await audio.get_file() suffix = ".ogg" if msg.audio and msg.audio.file_name: suffix = Path(msg.audio.file_name).suffix or ".ogg" with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp: tmp_path = tmp.name await tg_file.download_to_drive(tmp_path) log.info("Transkribiere %s ...", tmp_path) # Whisper API aufrufen with open(tmp_path, "rb") as f: transcript = client.audio.transcriptions.create( model="whisper-1", file=f, response_format="text", ) # Aufräumen os.unlink(tmp_path) text = transcript.strip() if isinstance(transcript, str) else transcript.text.strip() if text: await msg.reply_text(text) log.info("Transkription gesendet (%d Zeichen)", len(text)) else: await msg.reply_text("(Keine Sprache erkannt)") ``` ```python app.add_handler(CommandHandler("start", handle_start)) app.add_handler(MessageHandler(filters.VOICE | filters.AUDIO | filters.VIDEO_NOTE, handle_voice)) app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)) ``` ### Technical Analysis The media handler is registered for every Telegram user who can contact the bot. It does not verify ...[truncated 1850 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require an explicit allowlist of Telegram user IDs or chat IDs before downloading any media or invoking OpenAI. 2. Reject unauthorized requests without revealing operational details. 3. Add per-user and global rate limits, including burst and sustained-request limits. 4. Enforce maximum media size and duration before transcription. 5. Limit concurrent transcription jobs with a queue or semaphore. 6. Configure OpenAI project-level spending limits, usage alerts, and a dedicated restricted API key. 7. Record authorization failures and anomalous usage without logging credentials or sensitive transcript contents. 8. Consider restricting the bot to private chats or a controlled Telegram group. Example authorization gate: ```python ALLOWED_USER_IDS = { int(value) for value in os.environ.get("ALLOWED_USER_IDS", "").split(",") if value.strip() } async def handle_voice(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: msg = update.effective_message user = update.effective_user if not user or user.id not in ALLOWED_USER_IDS: log.warning("Rejected unauthorized Telegram user ID") return # Continue only after authorization. ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/install.sh:4
Finding
Installation Instructions Expose Secrets Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install.sh:4-10` and `SKILL.md:41-44` **Vulnerability Type**: Insecure credential handling **Risk Level**: Medium ### Vulnerable Code ```bash if [[ $# -lt 2 ]]; then echo "Usage: install.sh <telegram-bot-token> <openai-api-key>" >&2 exit 2 fi TELEGRAM_TOKEN="$1" OPENAI_KEY="$2" BOT_DIR="$HOME/transcribe-bot" ``` The documented invocation is: ```bash {baseDir}/scripts/install.sh <telegram-bot-token> <openai-api-key> ``` ### Technical Analysis The installer requires both the Telegram bot token and OpenAI API key as positional command-line arguments. Secrets entered this way may be exposed through: - Interactive shell history. - Process listings and process inspection interfaces while the installer runs. - Terminal session recording. - CI/CD job logs or automation telemetry. - Wrapper scripts, audit systems, or command-tracing features. The installer subsequently stores the credentials in `~/transcribe-bot/.env` and applies mode `600`. That file permission is an appropriate baseline and limits access to the owning user. However, it does not remediate exposure that occurs while the secrets are supplied as command-line arguments. The credentials are necessary for the declared transcription functionality, but accepting them through positional arguments exceeds the minimum exposure necessary. ### Attack Path 1. A user follows the documented setup command and places real credentials in the command line. 2. The command is retained by shell history, terminal recording, automation logs, or another command-observation mechanism. 3. A local user, administrator, monitoring service, or party with access to those records obtains the credential values. 4. The Telegram token is used to control or impersonate the bot, or the OpenAI key is used to make unauthorized billable API requests. Exploitation depends on access to process information, shell history, or installation logs; it does not independently ...[truncated 475 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not accept secrets as positional command-line arguments. 2. Prompt for each secret without terminal echo using `read -r -s`. 3. Alternatively, require a pre-created mode-`600` environment file and pass only its path to the installer. 4. Set a restrictive `umask`, such as `umask 077`, before creating credential files. 5. Write the file atomically and ensure the destination directory is owned by the current user. 6. Document credential rotation procedures in case command-line exposure has already occurred. 7. Use a dedicated OpenAI project key with minimal scope and spending limits. Example: ```bash umask 077 read -r -s -p "Telegram bot token: " TELEGRAM_TOKEN printf '\n' read -r -s -p "OpenAI API key: " OPENAI_KEY printf '\n' ENV_FILE="$HOME/transcribe-bot/.env" { printf 'TELEGRAM_BOT_TOKEN=%s\n' "$TELEGRAM_TOKEN" printf 'OPENAI_API_KEY=%s\n' "$OPENAI_KEY" } > "$ENV_FILE" chmod 600 "$ENV_FILE" unset TELEGRAM_TOKEN OPENAI_KEY ``` ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/install.sh:17
Finding
Runtime Dependencies Are Installed Without Version or Integrity Pinning<![CDATA[ ## Vulnerability Details **File Location**: `scripts/install.sh:17-21` and `SKILL.md:33-37` **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash # Create venv and install deps if [[ ! -d "$BOT_DIR/venv" ]]; then python3 -m venv "$BOT_DIR/venv" fi "$BOT_DIR/venv/bin/pip" install -q python-telegram-bot openai ``` The manual instructions repeat the same behavior: ```bash python3 -m venv ~/transcribe-bot/venv ~/transcribe-bot/venv/bin/pip install python-telegram-bot openai ``` ### Technical Analysis The installer requests `python-telegram-bot` and `openai` without exact versions, hashes, or a lock file. Consequently, the installed code depends on whichever versions and transitive dependencies the package index resolves at installation time. This makes installations non-reproducible and increases supply-chain risk. A compromised package release, compromised transitive dependency, unsafe future update, or package-index compromise could introduce code that executes during installation or when the persistent service starts. The package names appear legitimate and there is no evidence in the audited files of deliberate typosquatting, dependency confusion, or a malicious package source. The finding is therefore based on missing version and integrity controls, not evidence that the currently resolved packages are malicious. ### Attack Path 1. A direct or transitive dependency publishes a compromised or unsafe release, or the configured package source is compromised. 2. A user runs the installer after that release becomes the version selected by the resolver. 3. `pip` downloads and installs the unreviewed package because no exact version or hash is enforced. 4. Package installation hooks, imported module code, or runtime library code executes under the installing user's account. 5. At runtime, compromised dependency code may access the bot's environment, credentials, downloaded audio, n ...[truncated 730 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a reviewed dependency lock file containing exact versions for direct and transitive dependencies. 2. Pin package hashes and install with `--require-hashes`. 3. Generate locks in a controlled environment and review dependency updates before release. 4. Use a trusted package index explicitly and avoid unreviewed alternative indexes. 5. Run dependency vulnerability and provenance checks as part of release maintenance. 6. Preserve the lock file inside the audited Skill so installation resolves the reviewed dependency set. Example installation command: ```bash "$BOT_DIR/venv/bin/pip" install \ --require-hashes \ --only-binary=:all: \ -r "$SCRIPT_DIR/requirements.txt" ``` A version-only lock improves reproducibility, but cryptographic hashes should also be included to enforce artifact integrity. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (17)

Credential Access

High
Category
Privilege Escalation
Content
```bash
# Create environment file with secrets (restricted permissions)
cat > ~/transcribe-bot/.env << EOF
TELEGRAM_BOT_TOKEN=<your-token>
OPENAI_API_KEY=<your-key>
EOF
Confidence
84% confidence
Finding
The skill instructs users to place long-lived API credentials in a plaintext .env file under the home directory. While common, this increases the chance of credential disclosure through backups, accidental file exposure, shell history mistakes during creation, or compromise of the local account.

Credential Access

High
Category
Privilege Escalation
Content
TELEGRAM_BOT_TOKEN=<your-token>
OPENAI_API_KEY=<your-key>
EOF
chmod 600 ~/transcribe-bot/.env

# Create systemd service
cat > ~/.config/systemd/user/transcribe-bot.service << EOF
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
ExecStart=$HOME/transcribe-bot/venv/bin/python3 $HOME/transcribe-bot/bot.py
Restart=always
RestartSec=5
EnvironmentFile=$HOME/transcribe-bot/.env

[Install]
WantedBy=default.target
Confidence
78% confidence
Finding
Using EnvironmentFile in a systemd unit causes the service to load secrets from a plaintext file into the process environment. Environment variables can be exposed through debugging, process inspection by the same user, crash reports, or misconfigured logging, making this weaker than dedicated secret delivery mechanisms.

Credential Access

High
Category
Privilege Escalation
Content
# Create environment file with restricted permissions
mkdir -p "$BOT_DIR"
ENV_FILE="$BOT_DIR/.env"
cat > "$ENV_FILE" << EOF
TELEGRAM_BOT_TOKEN=$TELEGRAM_TOKEN
OPENAI_API_KEY=$OPENAI_KEY
Confidence
95% confidence
Finding
The script writes sensitive API credentials into a plaintext .env file. While intended for service operation, plaintext credential-at-rest storage creates a real credential exposure risk if the user account, home directory, backups, or developer tooling are compromised; the bot context makes this meaningful because both tokens grant access to external services and potentially billable API use.

Credential Access

High
Category
Privilege Escalation
Content
ExecStart=$BOT_DIR/venv/bin/python3 $BOT_DIR/bot.py
Restart=always
RestartSec=5
EnvironmentFile=$BOT_DIR/.env

[Install]
WantedBy=default.target
Confidence
84% confidence
Finding
Referencing the .env file via EnvironmentFile causes the long-running service to load credentials from disk on each start, extending the lifetime and operational dependence on persisted secrets. This is not exfiltration by itself, but it reinforces the credential exposure issue because the deployment design requires stable on-disk secret material for continued operation.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises and instructs shell-based installation and service management but does not declare any explicit tool scope such as permissions or allowed-tools. That creates a trust and review gap: a consumer may not realize the skill requires shell access, filesystem writes, package installation, and service persistence to operate.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill states that audio goes to OpenAI Whisper, but it does not present this as a prominent privacy warning or obtain clear user acknowledgment about third-party data transfer. Users may unknowingly send potentially sensitive voice data and metadata off-platform for processing.

Session Persistence

Medium
Category
Rogue Agent
Content
### 1. Install

```bash
mkdir -p ~/transcribe-bot
cp {baseDir}/scripts/bot.py ~/transcribe-bot/
python3 -m venv ~/transcribe-bot/venv
~/transcribe-bot/venv/bin/pip install python-telegram-bot openai
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.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The bot sends user-provided audio to OpenAI's Whisper API, which is an external third-party service, but the user-facing workflow does not clearly disclose that off-platform processing occurs. This creates a privacy and consent risk because users may reasonably assume Telegram messages are processed only by the bot operator or within Telegram, not transmitted to another provider.

Session Persistence

Medium
Category
Rogue Agent
Content
echo "Installing Telegram Transcribe Bot..."

# Copy bot script
mkdir -p "$BOT_DIR"
cp "$SCRIPT_DIR/bot.py" "$BOT_DIR/bot.py"

# Create venv and install deps
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.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The installer persists the Telegram bot token and OpenAI API key to a local .env file without explicitly warning the user that supplied credentials will be written to disk and reused by a long-running service. Even though file permissions are restricted to 600, persistence increases exposure through backups, local compromise, accidental disclosure, or later inspection by other processes running as the same user.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
TELEGRAM_BOT_TOKEN=$TELEGRAM_TOKEN
OPENAI_API_KEY=$OPENAI_KEY
EOF
chmod 600 "$ENV_FILE"

# Create systemd service
mkdir -p ~/.config/systemd/user
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
TELEGRAM_BOT_TOKEN=$TELEGRAM_TOKEN
OPENAI_API_KEY=$OPENAI_KEY
EOF
chmod 600 "$ENV_FILE"

# Create systemd service
mkdir -p ~/.config/systemd/user
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
EOF

systemctl --user daemon-reload
systemctl --user enable transcribe-bot
systemctl --user restart transcribe-bot

echo "✅ Transcribe Bot installiert und gestartet."
Confidence
80% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
EOF

systemctl --user daemon-reload
systemctl --user enable transcribe-bot
systemctl --user restart transcribe-bot

echo "✅ Transcribe Bot installiert und gestartet."
Confidence
80% 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.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
Natural-language strings in the module docstring and user-facing replies are consistently German, and the skill does not indicate that language is configurable or intentionally restricted to a German-only audience. This can violate language/locale policy where user-facing skills must not force a specific language without opt-in.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The script emits status messages in German only, which imposes a specific language on all users regardless of locale or preference. There is no indication that the skill is intentionally region-specific or that users can opt into German output.

Static analysis

No suspicious patterns detected.