Back to skill

Security audit

TMS (Telegram Media Server)

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent TMS controller, but it gives the agent destructive download deletion authority and can send an API key over non-local plaintext HTTP without enough guardrails.

Install only if the TMS API URL points to a trusted endpoint. Use HTTPS, VPN, or localhost for any API-key-protected TMS access, redact keys from screenshots, and configure OpenClaw so destructive delete requests require explicit user confirmation before execution.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:18
Finding
API Credentials May Be Transmitted Over Plaintext HTTP to a Configurable Remote Host## Vulnerability Details **File Location**: `SKILL.md:18-19` **Vulnerability Type**: Plaintext transmission of sensitive authentication credentials **Risk Level**: High ### Vulnerable Code Snippet ```markdown - **Base URL:** Use env `TMS_API_URL` if set; otherwise, when TMS and OpenClaw run on the **same host**, use **`http://127.0.0.1:8080`** (TMS default API listen). Do not add a trailing slash. All endpoint paths in the spec use the prefix `/api/v1` — e.g. `GET /health` means **`GET {BaseURL}/api/v1/health`**. - **Authentication:** If env `TMS_API_KEY` is configured, always send every API request with `Authorization: Bearer <TMS_API_KEY>` or header `X-API-Key: <TMS_API_KEY>`. If a request returns 401, retry once with the configured `TMS_API_KEY`; do not ask the user to reveal the key. Only omit auth when `TMS_API_KEY` is truly absent and TMS is explicitly configured to allow unauthenticated localhost requests. ``` The associated remote-host configuration example in `README.md:40-41` explicitly permits plaintext HTTP: ```markdown - `TMS_API_URL` — **optional.** Base URL of TMS API. When not set and agent runs on the same host as TMS, default is `http://127.0.0.1:8080`. Set when TMS is on another host (e.g. `http://tms-host:8080`). - `TMS_API_KEY` — **required when TMS has API auth enabled.** Ansible-generated installs set it by default. Configure it in OpenClaw skill env or `skills.entries.tms.apiKey`; the agent should not ask the user to paste it into chat. ``` `README.md:103` also demonstrates sending the credential to the configured URL without requiring HTTPS: ```markdown - **"API unreachable" / connection errors** — Check `TMS_API_URL` (no trailing slash), firewall, and that TMS is running with API enabled. Test: `curl "$TMS_API_URL/api/v1/health"` (from same host) or with key: `curl -H "Authorization: Bearer $TMS_API_KEY" "$TMS_API_URL/api/v1/health"`. ``` ### Technical Analysis The Skill allows `TMS_API_URL` ...[truncated 2525 chars]
Remediation
## Remediation Suggestions 1. Require `https://` for every non-loopback `TMS_API_URL`. 2. Permit plaintext HTTP only when the destination is a verified loopback address such as `127.0.0.1`, `[::1]`, or a strictly validated equivalent. 3. Refuse to attach `TMS_API_KEY` when the URL uses plaintext HTTP and is not loopback. 4. Replace the remote example `http://tms-host:8080` with an HTTPS URL. 5. Document secure deployment through TLS termination, a trusted reverse proxy, VPN, or mutually authenticated TLS. 6. Require normal certificate and hostname validation; do not recommend disabling TLS verification. 7. Do not forward authentication headers across redirects to another origin. Prefer disabling redirects for authenticated API calls unless the destination is explicitly validated. 8. Validate the configured URL scheme and destination before the first request, including after DNS resolution where feasible. 9. Use a dedicated, rotatable TMS key with the narrowest available permissions. If supported by TMS, separate read-only and destructive-operation credentials. 10. Rotate `TMS_API_KEY` immediately if it may previously have been sent over an untrusted plaintext network. 11. Update the troubleshooting command to reject or warn about authenticated plaintext remote URLs.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (10)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
## [1.0.8] - OpenClaw metadata and delete/list semantics

- **OpenClaw metadata:** shortened the frontmatter description, added homepage, set `user-invocable: false`, and changed `metadata.openclaw.primaryEnv` to `TMS_API_KEY`.
- **API semantics:** documented that `GET /downloads` includes queued, active, and completed/library items, and that `DELETE /downloads/{id}` removes the item everywhere.
- **ClawHub docs:** updated install/publish commands to the current `openclaw skills install` and `clawhub skill publish` flows.

## [1.0.7] - Add download via torrent_base64
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
|-----------|--------------|
| *"Add this link: https://youtube.com/watch?v=..."* | `POST /api/v1/downloads` with `{"url": "..."}`; reports back id and title. |
| *"What's downloading?"* | `GET /api/v1/downloads`; summarizes queued, active, and completed/library items. |
| *"Remove download 2"* | `DELETE /api/v1/downloads/2`; confirms removal everywhere. |
| *"Find torrents for Matrix 1080p"* | `GET /api/v1/search?q=Matrix%201080p`; can then add one via `POST /downloads` with magnet, torrent URL, or `torrent_base64` if the user provides a `.torrent` file. |

## ClawHub
Confidence
84% confidence
Finding
The skill explicitly exposes a destructive DELETE operation that removes downloads, files, database state, and qBittorrent entries. In an autonomous agent context, that creates a real risk of unintended or prompt-induced data deletion if the model invokes the action without strong user confirmation or weak parameter validation.

Self-Modification

High
Category
Rogue Agent
Content
## Publishing (for maintainers)

To publish or update this skill on ClawHub from the repo root:

1. Install CLI via npm (ClawHub is not in Homebrew): `npm i -g clawhub` or `pnpm add -g clawhub`.
2. Log in: `clawhub login` (or `clawhub login --token <token>`).
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
tags: [downloads]
      summary: Create a download
      description: |
        Call to add a download. Body: JSON with exactly one of "url" or "torrent_base64", plus optional "title". "url": video URL (yt-dlp), magnet (magnet:...), HTTPS URL to a .torrent file, or Prowlarr proxy download URL. "torrent_base64": standard Base64 of a .torrent file (no separate HTTP fetch). Prefer magnet from search results when applicable. If the user did not explicitly request a duplicate, call GET /downloads first and avoid adding an existing title. Response gives id (number) and title (string). Use this id for DELETE /downloads/{id}.
      operationId: addDownload
      requestBody:
        required: true
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

High
Confidence
98% confidence
Finding
The README explicitly suggests publishing a configuration screenshot that includes `TMS_API_KEY`, which creates a realistic risk of credential disclosure in public listings. Because this skill controls a Telegram Media Server over REST, exposing the API key could let third parties access or manipulate downloads and related server functions.

Ssd 3

High
Confidence
99% confidence
Finding
The documentation recommends including an API key in a screenshot intended for publication on ClawHub, which is a direct secret-exposure issue rather than a theoretical concern. In this skill's context, the exposed key could be reused against the TMS REST API to view, add, or delete downloads, making the published screenshot an actionable attack vector.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
**Install Telegram Media Server** (required before using this skill):

- **Repository:** [github.com/NikitaDmitryuk/telegram-media-server](https://github.com/NikitaDmitryuk/telegram-media-server)
- Clone, build, and configure as described in the project [README](https://github.com/NikitaDmitryuk/telegram-media-server#readme). The TMS REST API is enabled by default. Ansible installs generate `TMS_API_KEY` by default. Put that key in OpenClaw skill env or `skills.entries.tms.apiKey`; do not ask users to paste it into chat. Ensure the API listen address (`TMS_API_LISTEN`) is reachable from where OpenClaw runs.

## What it does
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Base URL and authentication

- **Base URL:** Use env `TMS_API_URL` if set; otherwise, when TMS and OpenClaw run on the **same host**, use **`http://127.0.0.1:8080`** (TMS default API listen). Do not add a trailing slash. All endpoint paths in the spec use the prefix `/api/v1` — e.g. `GET /health` means **`GET {BaseURL}/api/v1/health`**.
- **Authentication:** If env `TMS_API_KEY` is configured, always send every API request with `Authorization: Bearer <TMS_API_KEY>` or header `X-API-Key: <TMS_API_KEY>`. If a request returns 401, retry once with the configured `TMS_API_KEY`; do not ask the user to reveal the key. Only omit auth when `TMS_API_KEY` is truly absent and TMS is explicitly configured to allow unauthenticated localhost requests.

## Operations (summary)
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill documents a DELETE operation that removes downloads, local files, database/library rows, and qBittorrent entries 'everywhere' but provides no confirmation, preview, or user-consent guidance. In an agent setting, that omission increases the chance of irreversible destructive actions being triggered from ambiguous prompts or mistaken item selection.

Vague Triggers

Low
Confidence
90% confidence
Finding
This manifest describes the skill broadly as one that 'teaches OpenClaw to control a running TMS via REST' and lists many actions, but it does not define any specific activation phrases, scope limits, or exclusion conditions. In a manifest file, that lack of trigger specificity can make invocation conditions ambiguous and increase the chance of unintended activation.

Static analysis

No suspicious patterns detected.