Back to skill

Security audit

Crypto Price

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims: it fetches public crypto market data, generates charts, and stores short-lived chart/cache files, with no evidence of hidden data theft or persistence.

Install this only if you are comfortable sending crypto token lookup requests to CoinGecko and Hyperliquid and having temporary chart/cache files written under /tmp. For shared or multi-user hosts, prefer a hardened version that uses a private temp/cache directory and pinned dependencies.

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

Warning
Location
scripts/get_price_chart.py:37
Finding

Predictable Shared Temporary Files Permit Symlink Attacks and Cache Poisoning

Content
View full analysis
max_age_sec: return None try: with open(path, "r", encoding="utf-8") as handle: return json.load(handle) except (OSError, json.JSONDecodeError): return None def _write_cache(path, payload): try: with open(path, "w", encoding="utf-8") as handle: json.dump(payload, handle) except OSError: return ``` ```python ts = int(time.time()) chart_path = f"/tmp/crypto_chart_{symbol}_{ts}.png" fig.tight_layout() fig.savefig(chart_path, dpi=150) ``` ### Technical Analysis The Skill stores cache and chart files directly in the globally shared `/tmp` directory. Cache filenames are deterministic, while chart filenames contain only the requested symbol and a timestamp with one-second resolution. The files are accessed without: - A private, permission-restricted temporary directory - Exclusive file creation - Symbolic-link rejection - File ownership or regular-file validation - Atomic cache replacement The standard `open(path, "w")` operation used for cache files can follow a symbolic link placed at the predictable path. The matplotlib `fig.savefig()` operation similarly writes to a predictable pathname without first ensuring that the destination is a newly and securely created regular file. Cache reads also trust any syntactically valid and sufficiently recent JSON file already present at the expected path. A local attacker able to write to `/ ...[truncated 2110 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README states the skill is automatically triggered for broad categories like token prices, crypto charts, and cryptocurrency market data, which can cause the agent to invoke this skill for loosely related requests. Overly broad trigger scope increases the chance of unnecessary third-party API calls and unintended file creation, especially in agentic environments where skill routing is automatic.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill invokes a Python script that accesses external APIs and writes chart/cache files under /tmp, but the manifest declares no explicit tool scope or permission boundaries. That mismatch can lead to over-broad execution in environments that rely on manifest-declared capabilities for policy enforcement, increasing the chance of unintended network or filesystem access.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The description uses broad triggers like 'token price,' 'crypto price,' 'price chart,' and 'cryptocurrency market data,' which may cause the skill to activate for loosely related financial prompts. Over-broad activation increases the chance of unnecessary script execution, network requests, and file generation when the user did not specifically intend to invoke this skill.

Content

No source excerpt is available for this finding.

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 · README.md (reported line 134)May include surrounding context.

md
DEFAULT_HOURS = 24
CANDLE_MINUTES = 15
CACHE_TTL_SEC = 300
COINGECKO_PRICE_URL = "https://api.coingecko.com/api/v3/simple/price?ids={id}&vs_currencies={currency}"
COINGECKO_OHLC_URL = "https://api.coingecko.com/api/v3/coins/{id}/ohlc?vs_currency={currency}&days=1"
COINGECKO_SEARCH_URL = "https://api.coingecko.com/api/v3/search?query={query}"
COINGECKO_MARKET_CHART_URL = "https://api.coingecko.com/api/v3/coins/{id}/market_chart?vs_currency={currency}&days=1"

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/get_price_chart.py (reported line 16)May include surrounding context.

python
DEFAULT_HOURS = 24
CANDLE_MINUTES = 15
CACHE_TTL_SEC = 300
COINGECKO_PRICE_URL = "https://api.coingecko.com/api/v3/simple/price?ids={id}&vs_currencies={currency}"
COINGECKO_OHLC_URL = "https://api.coingecko.com/api/v3/coins/{id}/ohlc?vs_currency={currency}&days=1"
COINGECKO_SEARCH_URL = "https://api.coingecko.com/api/v3/search?query={query}"
COINGECKO_MARKET_CHART_URL = "https://api.coingecko.com/api/v3/coins/{id}/market_chart?vs_currency={currency}&days=1"

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/get_price_chart.py (reported line 17)May include surrounding context.

python
DEFAULT_HOURS = 24
CANDLE_MINUTES = 15
CACHE_TTL_SEC = 300
COINGECKO_PRICE_URL = "https://api.coingecko.com/api/v3/simple/price?ids={id}&vs_currencies={currency}"
COINGECKO_OHLC_URL = "https://api.coingecko.com/api/v3/coins/{id}/ohlc?vs_currency={currency}&days=1"
COINGECKO_SEARCH_URL = "https://api.coingecko.com/api/v3/search?query={query}"
COINGECKO_MARKET_CHART_URL = "https://api.coingecko.com/api/v3/coins/{id}/market_chart?vs_currency={currency}&days=1"

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/get_price_chart.py (reported line 18)May include surrounding context.

python
DEFAULT_HOURS = 24
CANDLE_MINUTES = 15
CACHE_TTL_SEC = 300
COINGECKO_PRICE_URL = "https://api.coingecko.com/api/v3/simple/price?ids={id}&vs_currencies={currency}"
COINGECKO_OHLC_URL = "https://api.coingecko.com/api/v3/coins/{id}/ohlc?vs_currency={currency}&days=1"
COINGECKO_SEARCH_URL = "https://api.coingecko.com/api/v3/search?query={query}"
COINGECKO_MARKET_CHART_URL = "https://api.coingecko.com/api/v3/coins/{id}/market_chart?vs_currency={currency}&days=1"

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/get_price_chart.py (reported line 19)May include surrounding context.

python
DEFAULT_HOURS = 24
CANDLE_MINUTES = 15
CACHE_TTL_SEC = 300
COINGECKO_PRICE_URL = "https://api.coingecko.com/api/v3/simple/price?ids={id}&vs_currencies={currency}"
COINGECKO_OHLC_URL = "https://api.coingecko.com/api/v3/coins/{id}/ohlc?vs_currency={currency}&days=1"
COINGECKO_SEARCH_URL = "https://api.coingecko.com/api/v3/search?query={query}"
COINGECKO_MARKET_CHART_URL = "https://api.coingecko.com/api/v3/coins/{id}/market_chart?vs_currency={currency}&days=1"

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/get_price_chart.py (reported line 20)May include surrounding context.

python
DEFAULT_HOURS = 24
CANDLE_MINUTES = 15
CACHE_TTL_SEC = 300
COINGECKO_PRICE_URL = "https://api.coingecko.com/api/v3/simple/price?ids={id}&vs_currencies={currency}"
COINGECKO_OHLC_URL = "https://api.coingecko.com/api/v3/coins/{id}/ohlc?vs_currency={currency}&days=1"
COINGECKO_SEARCH_URL = "https://api.coingecko.com/api/v3/search?query={query}"
COINGECKO_MARKET_CHART_URL = "https://api.coingecko.com/api/v3/coins/{id}/market_chart?vs_currency={currency}&days=1"

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 · README.md (reported line 130)May include surrounding context.

md
COINGECKO_SEARCH_URL = "https://api.coingecko.com/api/v3/search?query={query}"
COINGECKO_MARKET_CHART_URL = "https://api.coingecko.com/api/v3/coins/{id}/market_chart?vs_currency={currency}&days=1"
COINGECKO_MARKET_CHART_DAYS_URL = "https://api.coingecko.com/api/v3/coins/{id}/market_chart?vs_currency={currency}&days={days}"
HYPERLIQUID_INFO_URL = "https://api.hyperliquid.xyz/info"

TOKEN_ID_MAP = {
    "HYPE": "hyperliquid",

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/get_price_chart.py (reported line 21)May include surrounding context.

python
COINGECKO_SEARCH_URL = "https://api.coingecko.com/api/v3/search?query={query}"
COINGECKO_MARKET_CHART_URL = "https://api.coingecko.com/api/v3/coins/{id}/market_chart?vs_currency={currency}&days=1"
COINGECKO_MARKET_CHART_DAYS_URL = "https://api.coingecko.com/api/v3/coins/{id}/market_chart?vs_currency={currency}&days={days}"
HYPERLIQUID_INFO_URL = "https://api.hyperliquid.xyz/info"

TOKEN_ID_MAP = {
    "HYPE": "hyperliquid",

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README mentions external APIs, caching, and chart output, but it does not clearly present these as privacy- and filesystem-relevant behaviors to users. In an agent skill context, lack of explicit disclosure can lead to users unknowingly sending query data to third parties and leaving artifacts in /tmp, which is a transparency and operational risk.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The dependency is only lower-bounded (matplotlib>=3.5.0), so installations may resolve to different future versions with unreviewed changes or known-bad releases. This weakens build reproducibility and increases supply-chain risk, though in this skill the package is a common plotting library and the file contains no stronger indicators of malicious intent.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
matplotlib>=3.5.0

Static analysis

No suspicious patterns detected.