Back to skill

Security audit

Trading Signals Ws

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its trading-alert purpose, but its docs encourage root-level auto-start deployment and include an under-explained external subscription API.

Review before installing. Prefer a virtual environment with pinned dependencies, run the bot as an unprivileged user or user-level service, avoid storing Telegram tokens in plaintext files, protect logs, and do not use the hosted Tinyore subscription/API examples unless you intentionally want to share the shown data with that service.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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)

T06 · System Persistence

Error
Location
SKILL.md:56
Finding
Persistent systemd service runs the bot with unnecessary root privileges<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 56–72 **Vulnerability Type**: System-wide persistence and excessive service privileges **Risk Level**: High ### Vulnerable Code ```bash # systemd service sudo tee /etc/systemd/system/signal-bot.service << 'EOF' [Unit] Description=Trading Signal Bot After=network.target [Service] Type=simple WorkingDirectory=/root/signals ExecStart=/usr/bin/python3 signal_bot.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target EOF sudo systemctl enable --now signal-bot ``` ### Technical Analysis The deployment instructions use `sudo` to create a system-wide systemd unit and enable it at boot. The service also uses `/root/signals` as its working directory and does not specify a `User=` or `Group=` directive. System services run as root by default when no service account is configured. `Restart=always` and `systemctl enable` cause the process to restart after failures and execute again after system reboots. Running continuously is reasonable for a real-time monitoring bot, but system-wide root persistence is not necessary for its declared functions. The bot only needs outbound network access and write access to its state and log files. The unit also lacks systemd hardening controls such as: - `NoNewPrivileges=true` - `ProtectSystem=strict` - `ProtectHome=true` - `PrivateTmp=true` - `CapabilityBoundingSet=` - `RestrictAddressFamilies=` - A dedicated, narrowly writable state directory Consequently, the bot itself and every imported Python dependency execute with root privileges. Any future compromise of the script, configuration, working directory, or dependency would inherit those privileges and the service's cross-session persistence. ### Attack Path 1. A user follows the documented deployment instructions with `sudo`. 2. A root-level service is installed under `/etc/systemd/system/`. 3. The service is enabled at boot and configured to restart indefinitely. 4. An attacker compromises ...[truncated 924 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a dedicated unprivileged service account with no interactive login. 2. Set explicit `User=` and `Group=` directives in the unit. 3. Store code outside `/root`, such as `/opt/signal-bot`, and place writable state under `/var/lib/signal-bot`. 4. Grant write access only to the state and log locations required by the application. 5. Add systemd sandboxing directives, for example: ```ini [Service] Type=simple User=signalbot Group=signalbot WorkingDirectory=/opt/signal-bot ExecStart=/opt/signal-bot/.venv/bin/python /opt/signal-bot/scripts/signal_bot.py Restart=on-failure RestartSec=10 NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ProtectKernelTunables=true ProtectKernelModules=true ProtectControlGroups=true LockPersonality=true RestrictSUIDSGID=true CapabilityBoundingSet= ReadWritePaths=/var/lib/signal-bot /var/log/signal-bot RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 ``` 6. Prefer a user-level systemd unit where system-wide startup is not required. 7. Clearly label persistent deployment as optional and document removal: ```bash sudo systemctl disable --now signal-bot sudo rm /etc/systemd/system/signal-bot.service sudo systemctl daemon-reload ``` 8. Protect the service working directory from modification by the runtime account. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:12
Finding
Unpinned third-party dependencies create a supply-chain execution risk<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 12 **Vulnerability Type**: Unpinned dependency installation from a mutable package index **Risk Level**: Medium ### Vulnerable Code ```bash pip install websockets ccxt requests ``` ### Technical Analysis The installation command does not specify package versions, hashes, a lockfile, or an isolated virtual environment. Installation results therefore depend on whichever releases the package index resolves at execution time. A future compromised, malicious, or incompatible release could execute code during package installation, module import, or normal bot operation. This risk becomes substantially more severe when combined with the documented root-level systemd service, because imported package code would run with the service's root privileges. The reviewed project does not demonstrate that the named packages are currently malicious. The vulnerability is the absence of controls ensuring that installed dependency artifacts are the exact versions reviewed and tested. ### Attack Path 1. A user executes the documented unpinned `pip install` command. 2. The package index resolves dependency versions at installation time. 3. A package account, release, transitive dependency, or distribution artifact is compromised. 4. The compromised package executes code during installation or when imported by `signal_bot.py`. 5. If deployed using the documented system service, the package subsequently executes as root and is restarted across reboots. ### Impact Assessment The immediate scope is arbitrary code execution under the account installing or running the dependencies. Under the documented deployment configuration, this can become persistent root-level code execution. Additional effects can include credential theft, Telegram bot-token disclosure, modification of generated alerts, state-file manipulation, unauthorized network communication, or complete host compromise. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create and use an isolated virtual environment: ```bash python3 -m venv .venv . .venv/bin/activate ``` 2. Provide a reviewed requirements or lock file containing exact versions. 3. Pin transitive dependencies as well as direct dependencies. 4. Generate and verify cryptographic hashes, then install with: ```bash pip install --require-hashes -r requirements.txt ``` 5. Use a controlled package index or approved internal mirror where appropriate. 6. Add automated dependency vulnerability and integrity scanning. 7. Review dependency updates before changing the lockfile. 8. Never install or run these dependencies as root unless strictly unavoidable. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/signal_bot.py:33
Finding
Telegram bot token may be exposed through exception logging<![CDATA[ ## Vulnerability Details **File Location**: `scripts/signal_bot.py`, lines 33–43 **Vulnerability Type**: Sensitive token embedded in a request URL and potentially written to logs **Risk Level**: Medium ### Vulnerable Code ```python def send_tg(msg: str): if not config.TG_BOT_TOKEN: log.info(f"[TG disabled] {msg}") return try: requests.post( f"https://api.telegram.org/bot{config.TG_BOT_TOKEN}/sendMessage", json={"chat_id": config.TG_CHAT_ID, "text": msg, "parse_mode": "HTML"}, timeout=10, ) except Exception as e: log.error(f"TG error: {e}") ``` ### Technical Analysis Telegram's Bot API requires the bot token to appear in the URL path. The code then logs the complete string representation of any request exception. Exceptions produced by HTTP client and connection layers can include the requested URL. For example, proxy, retry, DNS, TLS, or connection errors may retain or render request details containing the URL. Because the token is part of that URL, logging the raw exception can disclose it to `signal_bot.log`. The project configures a file logger at startup: ```python handlers=[logging.FileHandler("signal_bot.log"), logging.StreamHandler()], ``` No explicit restrictive file permissions or token-redaction filter is configured. The precise accessibility of the log depends on the process account, working directory, and host permissions, but disclosure is possible whenever another party can read the generated log or collected service output. ### Attack Path 1. The bot is configured with a valid Telegram bot token. 2. A Telegram API request experiences a network, proxy, TLS, DNS, or connection-layer failure. 3. The resulting exception includes the request URL or related request details. 4. The code writes the raw exception to the file log and standard error. 5. A local user, log collector, support recipient, or attacker with log access obtains the token. 6. T ...[truncated 640 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not log raw request exceptions without sanitization. 2. Redact the configured token from every error message before logging: ```python except requests.RequestException as exc: error = str(exc).replace(config.TG_BOT_TOKEN, "[REDACTED]") log.error("Telegram request failed: %s", error) ``` 3. Prefer logging a fixed error category and exception class rather than the full exception: ```python except requests.RequestException as exc: log.error("Telegram request failed: %s", type(exc).__name__) ``` 4. Avoid logging request URLs, headers, payloads, or response bodies when they may contain credentials. 5. Add a centralized logging filter that redacts Telegram tokens and other configured secrets. 6. Configure restrictive log ownership and permissions, and avoid placing logs in broadly readable directories. 7. Ensure external log collectors also apply secret redaction and access controls. 8. Rotate the Telegram bot token immediately if it may already have appeared in logs. 9. Catch `requests.RequestException` rather than the overly broad `Exception`, while handling unexpected programming failures separately. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (21)

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill documents capabilities that involve environment secrets, local file access, persistence, and network communication, but it does not declare any tool scope or permissions boundaries in the manifest. This increases the chance that an agent invokes the skill with broader-than-necessary access, making unintended credential use, file modification, or outbound transmission harder to review and constrain.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The manifest description lists several broad activation contexts such as 'price alert system' and 'market monitor' without defining clear trigger boundaries or exclusions. In a manifest file, this can make invocation conditions ambiguous and overlap with common crypto-monitoring requests that may not specifically require this WebSocket Telegram bot skill.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The configuration example instructs users to place Telegram credentials into a local config and describes sending alerts to Telegram without an explicit warning that messages and identifiers are transmitted to a third party. This can lead users or agents to handle secrets and market activity data without informed consent or proper secret-management practices.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# systemd service
sudo tee /etc/systemd/system/signal-bot.service << 'EOF'
[Unit]
Description=Trading Signal Bot
After=network.target
Confidence
88% confidence
Finding
The deployment instructions tell the user to use sudo to write a systemd unit under /etc/systemd/system, which requires elevated privileges and creates a persistent service. If the referenced bot script or working directory is tampered with, this setup can run attacker-controlled code automatically with elevated operational trust on boot.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now signal-bot
```

## Live Signal API (Optional)
Confidence
86% confidence
Finding
Enabling the service with sudo creates persistence and causes the bot to start automatically, which amplifies the impact of any malicious or compromised script in the deployment directory. In a skill context, persistent autorun instructions are more dangerous because users may follow them directly from documentation without reviewing the full trust chain.

Session Persistence

Medium
Category
Rogue Agent
Content
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now signal-bot
```

## Live Signal API (Optional)
Confidence
90% confidence
Finding
The `systemctl enable` instruction establishes session persistence by configuring the bot to start automatically after reboot. Persistence is not inherently malicious, but in documentation for a networked bot with file/network access, providing autorun steps without stronger safety guidance increases the risk of long-lived unintended execution and harder-to-notice compromise.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The documentation introduces a hosted subscription/API service that is outside the core local WebSocket-to-Telegram bot purpose described in the manifest. Mixing an unrelated monetized external service into operational instructions can steer users or agents toward third-party data sharing and network calls they did not intend, increasing supply-chain and privacy risk.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The hosted API example requests the user's email and transmits it to a third-party subscription endpoint without an explicit privacy notice, retention statement, or consent language. This creates a clear privacy and data-sharing risk, especially because the section is embedded in what otherwise appears to be local bot setup documentation.

External Transmission

Medium
Category
Data Exfiltration
Content
```
# Free tier (15-min delayed)
curl https://api.tinyore.com/signals/free

# Get API key (7-day free trial)
curl -X POST https://api.tinyore.com/subscribe -H "Content-Type: application/json" -d '{"email":"you@example.com"}'
Confidence
91% confidence
Finding
This section instructs outbound requests to a third-party hosted service, including a POST that transmits an email address. External transmission is expected for some integrations, but here it is not clearly scoped in the manifest and is presented without trust, privacy, or validation guidance, increasing the risk of unintended data disclosure.

External Transmission

Medium
Category
Data Exfiltration
Content
```
# Free tier (15-min delayed)
curl https://api.tinyore.com/signals/free

# Get API key (7-day free trial)
curl -X POST https://api.tinyore.com/subscribe -H "Content-Type: application/json" -d '{"email":"you@example.com"}'
Confidence
91% confidence
Finding
This section instructs outbound requests to a third-party hosted service, including a POST that transmits an email address. External transmission is expected for some integrations, but here it is not clearly scoped in the manifest and is presented without trust, privacy, or validation guidance, increasing the risk of unintended data disclosure.

External Transmission

Medium
Category
Data Exfiltration
Content
curl https://api.tinyore.com/signals/free

# Get API key (7-day free trial)
curl -X POST https://api.tinyore.com/subscribe -H "Content-Type: application/json" -d '{"email":"you@example.com"}'

# Pro tier (real-time, $5/mo)
curl https://api.tinyore.com/signals/live -H "X-API-Key: YOUR_KEY"
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
curl https://api.tinyore.com/signals/free

# Get API key (7-day free trial)
curl -X POST https://api.tinyore.com/subscribe -H "Content-Type: application/json" -d '{"email":"you@example.com"}'

# Pro tier (real-time, $5/mo)
curl https://api.tinyore.com/signals/live -H "X-API-Key: YOUR_KEY"
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
curl https://api.tinyore.com/signals/free

# Get API key (7-day free trial)
curl -X POST https://api.tinyore.com/subscribe -H "Content-Type: application/json" -d '{"email":"you@example.com"}'

# Pro tier (real-time, $5/mo)
curl https://api.tinyore.com/signals/live -H "X-API-Key: YOUR_KEY"
Confidence
50% 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
94% confidence
Finding
The documentation repeatedly shows a Telegram bot token embedded directly in URLs, shell commands, Python config, and environment-variable examples without any warning that the token is a secret credential. In this context, users commonly copy-paste examples into shell history, shared docs, screenshots, or source files, which can expose the bot token and allow unauthorized parties to control the bot and read or send messages via the Telegram API.

External Transmission

Medium
Category
Data Exfiltration
Content
## Test It

```bash
curl -s "https://api.telegram.org/bot<TOKEN>/sendMessage" \
  -d "chat_id=<CHAT_ID>" \
  -d "text=Test signal 🚀" \
  -d "parse_mode=HTML"
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 function sends message content to the Telegram Bot API, which is a network operation transmitting potentially sensitive operational data off-system. Although logging exists for failures and disabled mode, there is no confirmation prompt or explicit user-facing warning that signal/status content will be sent to a third-party service.

External Transmission

Medium
Category
Data Exfiltration
Content
log.info(f"[TG disabled] {msg}")
        return
    try:
        requests.post(
            f"https://api.telegram.org/bot{config.TG_BOT_TOKEN}/sendMessage",
            json={"chat_id": config.TG_CHAT_ID, "text": msg, "parse_mode": "HTML"},
            timeout=10,
Confidence
80% 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
return
    try:
        requests.post(
            f"https://api.telegram.org/bot{config.TG_BOT_TOKEN}/sendMessage",
            json={"chat_id": config.TG_CHAT_ID, "text": msg, "parse_mode": "HTML"},
            timeout=10,
        )
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
return
    try:
        requests.post(
            f"https://api.telegram.org/bot{config.TG_BOT_TOKEN}/sendMessage",
            json={"chat_id": config.TG_CHAT_ID, "text": msg, "parse_mode": "HTML"},
            timeout=10,
        )
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
return
    try:
        requests.post(
            f"https://api.telegram.org/bot{config.TG_BOT_TOKEN}/sendMessage",
            json={"chat_id": config.TG_CHAT_ID, "text": msg, "parse_mode": "HTML"},
            timeout=10,
        )
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

Low
Confidence
86% confidence
Finding
The bot stores signal history, last-signal timestamps, prices, and update metadata in signal_state.json, which affects local user/system data. The write is not accompanied by any confirmation, warning comment, or explicit disclosure that runtime data will be persisted.

Static analysis

No suspicious patterns detected.