Back to skill

Security audit

BTC Monitor TalentverseX

Security checks for vulnerabilities and agentic risk

Overview

This BTC/ETH monitor is mostly coherent, but its optional cron installer can create unsafe persistent scheduled execution from unvalidated config.

Review before installing. Running the one-shot monitor is comparatively low risk, but avoid scripts/setup_cron.sh unless you trust and inspect config.json, understand the exact cron entry being installed, and are prepared to remove it manually. Enable Discord only if you are comfortable sending the generated market report to a configured Discord channel using a bot token from your environment.

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
scripts/setup_cron.sh:17
Finding

Unvalidated Cron Schedule Enables Persistent Command Injection

Content
View full analysis
> $LOG_DIR/monitor.log 2>&1 $CRON_MARKER" (crontab -l 2>/dev/null | grep -v "$CRON_MARKER" || true; echo "$CRON_JOB") | crontab - ``` ### Technical Analysis The script reads the `schedule` property from `config.json` and inserts it directly at the beginning of a crontab entry. It does not verify that the value: - Is a string containing only one line. - Contains exactly the expected cron scheduling fields. - Does not contain an embedded command after the scheduling fields. - Does not contain carriage returns, newline characters, NUL bytes, or other control characters. - Does not use cron directives or special syntax outside the supported schedule format. A crontab line consists of scheduling fields followed by an arbitrary shell command. Consequently, an attacker-controlled schedule can place a command immediately after valid scheduling fields, causing the intended monitor command to become additional shell syntax. Newline characters can also create entirely separate cron entries. For example, a malicious configuration could use a value conceptually equivalent to: ```json { "schedule": "* * * * * attacker_command #" } ``` After concatenation, the resulting entry would execute `attacker_command`, while the comment character prevents the intended monitoring command from affecting execution. A multiline value could install additional independent scheduled jobs. The exploit requires the attacker to influence `config.json` before a u ...[truncated 1731 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (17)

Tainted flow: 'headers' from os.getenv (line 504, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/monitor.py (reported line 104)May include surrounding context.

python
def post_json(url: str, *, headers: dict[str, str], payload: dict[str, Any], timeout: int = DEFAULT_TIMEOUT) -> Any:
    response = requests.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()
    return response.json()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill advertises executable behavior that reads configuration files, accesses environment variables, and makes network requests, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an authorization gap: a host or reviewer cannot easily determine from the manifest what capabilities the skill expects, increasing the risk of unintended data access or outbound communication when the skill is executed.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · docs/TROUBLESHOOTING.md (reported line 26)May include surrounding context.

md
## Cron job does not run

- Run `crontab -l` and verify the installed entry
- Check `logs/monitor.log`
- Make sure the machine timezone matches your expected schedule

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/monitor.py (reported line 104)May include surrounding context.

python
def post_json(url: str, *, headers: dict[str, str], payload: dict[str, Any], timeout: int = DEFAULT_TIMEOUT) -> Any:
    response = requests.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()
    return response.json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/monitor.py (reported line 111)May include surrounding context.

python
def get_binance_klines(symbol: str, interval: str, limit: int, timeout: int) -> list[list[Any]]:
    return request_json(
        "https://api.binance.com/api/v3/klines",
        params={"symbol": symbol, "interval": interval, "limit": limit},
        timeout=timeout,
    )

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/monitor.py (reported line 119)May include surrounding context.

python
def get_bybit_klines(symbol: str, limit: int, timeout: int) -> list[list[Any]]:
    data = request_json(
        "https://api.bybit.com/v5/market/kline",
        params={"category": "linear", "symbol": symbol, "interval": "W", "limit": limit},
        timeout=timeout,
    )

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/monitor.py (reported line 144)May include surrounding context.

python
def get_coingecko_weekly_klines(coin_id: str, limit: int, timeout: int) -> list[list[Any]]:
    days = 365
    data = request_json(
        f"https://api.coingecko.com/api/v3/coins/{coin_id}/market_chart",
        params={"vs_currency": "usd", "days": days, "interval": "daily"},
        timeout=timeout,
    )

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/monitor.py (reported line 292)May include surrounding context.

python
def get_coingecko_weekly_klines(coin_id: str, limit: int, timeout: int) -> list[list[Any]]:
    days = 365
    data = request_json(
        f"https://api.coingecko.com/api/v3/coins/{coin_id}/market_chart",
        params={"vs_currency": "usd", "days": days, "interval": "daily"},
        timeout=timeout,
    )

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/monitor.py (reported line 308)May include surrounding context.

python
def get_coingecko_weekly_klines(coin_id: str, limit: int, timeout: int) -> list[list[Any]]:
    days = 365
    data = request_json(
        f"https://api.coingecko.com/api/v3/coins/{coin_id}/market_chart",
        params={"vs_currency": "usd", "days": days, "interval": "daily"},
        timeout=timeout,
    )

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/monitor.py (reported line 310)May include surrounding context.

python
def get_coingecko_weekly_klines(coin_id: str, limit: int, timeout: int) -> list[list[Any]]:
    days = 365
    data = request_json(
        f"https://api.coingecko.com/api/v3/coins/{coin_id}/market_chart",
        params={"vs_currency": "usd", "days": days, "interval": "daily"},
        timeout=timeout,
    )

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/monitor.py (reported line 278)May include surrounding context.

python
def get_fear_greed_index(timeout: int) -> int | None:
    try:
        data = request_json("https://api.alternative.me/fng/", timeout=timeout)
    except requests.RequestException:
        return None
    entries = data.get("data") or []

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest emphasizes market monitoring with public API data and only briefly notes optional Discord delivery. In code, the skill not only reads public market data but can also authenticate with a secret token and perform outbound writes to a Discord channel, which is a materially broader behavior than passive monitoring.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

When enabled, the skill sends generated report content to Discord, an external third-party service, without any in-file consent prompt or prominent disclosure at send time. Even if the current report only contains market data, future configuration or report content could include sensitive operational details, and users may not realize that enabling the feature transmits data off-platform.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

A monitor based on public BTC/ETH market APIs is expected to fetch and analyze public data. Reading a bot token from the environment and using it to post authenticated messages adds a credential-handling and remote-write capability that goes beyond the core monitoring purpose unless clearly declared as part of scope.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
85% 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.

Content

Scanner excerpt · scripts/setup_cron.sh (reported line 13)May include surrounding context.

sh
exit 1
fi

if ! command -v crontab >/dev/null 2>&1; then
  echo "crontab is required."
  exit 1
fi

Session Persistence

Medium
Category
Rogue Agent
Confidence
95% confidence
Finding

This line installs a persistent cron entry for the current user, causing scripts/monitor.py to run on a recurring schedule from config.json. Although likely intended as normal functionality for a market-monitoring skill, persistence mechanisms are security-relevant because they survive the current session and can be abused if the monitored script, working directory, or configuration is later modified by an attacker.

Content

Scanner excerpt · scripts/setup_cron.sh (reported line 31)May include surrounding context.

sh
CRON_MARKER="# btc-monitor-skill"
CRON_JOB="$SCHEDULE cd $ROOT_DIR && /usr/bin/env python3 scripts/monitor.py >> $LOG_DIR/monitor.log 2>&1 $CRON_MARKER"

(crontab -l 2>/dev/null | grep -v "$CRON_MARKER" || true; echo "$CRON_JOB") | crontab -

echo "Cron installed: $SCHEDULE"
echo "Log file: $LOG_DIR/monitor.log"

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.