Back to skill

Security audit

trade-arena

Security checks for vulnerabilities and agentic risk

Overview

This virtual-trading skill mostly matches its purpose, but it can silently replace its own code from an unverified remote download.

Install only if you are comfortable with a trading competition skill that stores an API token locally and can modify its own installed files. Prefer disabling or avoiding self-update, using check-only updates, protecting config.json, and confirming buy/sell actions and task creation explicitly.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/quickstart.py:275
Finding

Silent self-update installs unverified remote code from an unrestricted download URL

Content
View full analysis
str: if not page_html: return "" labeled = re.search(r'href="([^"]+)"[^>]*>\s*Download zip\s*<', page_html, flags=re.IGNORECASE) if labeled: return urljoin(CLAW_HUB_SKILL_PAGE_URL, labeled.group(1)) fallback = re.search(r'href="([^"]*api/v1/download\?slug=trade-arena[^"]*)"', page_html, flags=re.IGNORECASE) if fallback: return urljoin(CLAW_HUB_SKILL_PAGE_URL, fallback.group(1)) return "" ``` ```python def fetch_clawhub_release_metadata() -> dict: response = requests.get(CLAW_HUB_SKILL_PAGE_URL, timeout=30) if response.status_code != 200: raise RuntimeError(f"http_{response.status_code}") page_html = response.text remote_version = _extract_clawhub_version(page_html) hosted_url = _extract_clawhub_download_url(page_html) if not hosted_url: raise RuntimeError("missing_download_url") if not remote_version: remote_version = _resolve_version_from_download(hosted_url) if not remote_version: raise RuntimeError("missing_version") return {"version": remote_version, "hosted_url": hosted_url} ``` ```python def apply_skill_update(hosted_url: str, target_version: str, silent: bool = False) -> bool: """Download through the hosted link and overwrite local skill files while preserving local c ...[truncated 3890 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/quickstart.py:163
Finding

ZIP path containment check can be bypassed during update extraction

Content
View full analysis
None: destination_resolved = destination.resolve() for member in archive.infolist(): target = (destination / member.filename).resolve() if not str(target).startswith(str(destination_resolved)): raise ValueError("Unsafe archive path detected; update aborted") archive.extractall(destination) ``` ### Technical Analysis The implementation attempts to prevent ZIP path traversal by resolving each destination and checking whether its string representation starts with the extraction directory string. String-prefix comparison does not establish filesystem ancestry. For example, if the intended directory is `/tmp/trade_arena_update_abc`, a resolved path under `/tmp/trade_arena_update_abc_evil/file` still begins with the same character sequence even though it is outside the intended directory. A crafted archive entry containing parent-directory components can exploit this boundary confusion. The implementation also delegates extraction to `ZipFile.extractall()` after validation and does not explicitly reject absolute paths, symbolic links, special files, or inconsistent path representations. Because update archives are remotely supplied, archive extraction must be treated as processing attacker-controlled input. ### Attack Path 1. An attacker gains control of the update archive through the unverified update channel. 2. The attacker creates a ZIP entry with parent-directory components that resolve to a sibling path sharing the extraction directory's string prefix. 3. `_safe_extract()` resolves the target and performs the vulnerable `startswith()` comparison. 4. The sibling path passes the string-prefix check despite being outside the extraction ...[truncated 919 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/quickstart.py:264
Finding

Bearer token can be transmitted to an arbitrary server configured through config.json

Content
View full analysis
str: normalized = (api_url or "").rstrip("/") if not normalized.startswith(("http://", "https://")): normalized = f"https://{normalized}" return normalized ``` ```python def api_request(method, endpoint, data=None, token=None): config = load_config() api_url = _normalize_api_url(config["api_url"]) url = f"{api_url}{endpoint}" headers = {"Content-Type": "application/json"} if token: headers["Authorization"] = f"Bearer {token}" return requests.request(method, url, json=data, headers=headers, timeout=30) ``` ```json { "api_url": "stock.cocoloop.cn", "token": "" } ``` ### Technical Analysis Authenticated requests derive their destination directly from the writable `api_url` field in `config.json`. The normalization function only adds a scheme when one is absent; it does not verify that the hostname is the official service, require HTTPS for explicitly supplied URLs, reject embedded user information, restrict ports, or enforce a trusted origin. When a token is supplied, the same function places it in the `Authorization` header regardless of the configured destination. Any local process, malicious update, unsafe configuration import, or user action that changes `api_url` can redirect a subsequent authenticated request to an attacker-controlled server. The default configuration uses the expected service, so exploitation requires configuration modification. Nevertheless, credential destinations should not be controlled by the same untrusted configuration that stores the credential. ### Attack Path 1. An attacker or malicious update modifies `config.json` and sets `api_url` to an attacker-co ...[truncated 953 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/quickstart.py:442
Finding

Live bearer-token prefixes are exposed in terminal and log output

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The English-language mismatch finding is substantively the same issue: the documented purpose emphasizes trading features, while the content also authorizes remote package download, parsing hosted metadata, and modifying local files. In a skill that handles API tokens and financial actions, hidden or under-disclosed maintenance behavior materially increases risk because compromise of the update path can lead to credential theft or arbitrary logic changes.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The English-language mismatch finding is substantively the same issue: the documented purpose emphasizes trading features, while the content also authorizes remote package download, parsing hosted metadata, and modifying local files. In a skill that handles API tokens and financial actions, hidden or under-disclosed maintenance behavior materially increases risk because compromise of the update path can lead to credential theft or arbitrary logic changes.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
98% confidence
Finding

The documented self_update_skill capability is a direct self-modification mechanism that can fetch and replace local skill code. In the context of a trading skill that also stores authentication tokens locally, self-modification is especially dangerous because a compromised update channel can change behavior, exfiltrate credentials, or alter trading logic without clear user awareness.

Content

Scanner excerpt · SKILL.md (reported line 589)May include surrounding context.

md
---

#### `self_update_skill`

主动触发 Skill 更新检查。若发现更新则通过托管链接下载并更新;支持仅检查不更新。日常主动运行时也会静默执行同样的检查。

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The auto-update mechanism fetches remote metadata, determines whether a remote version is newer, downloads a zip, and replaces local files automatically. This is especially dangerous in a skill context because users expect portfolio and API-helper functionality, not code replacement logic, so the behavior is both high-risk and weakly justified by the declared purpose.

Content

No source excerpt is available for this finding.

Self-Modification

High
Category
Rogue Agent
Confidence
97% confidence
Finding

A tool explicitly named self_update_skill introduces self-modification capability, which is especially dangerous in an agent skill because it can change future behavior, permissions, or embedded logic after deployment. In the context of a trading skill, this capability is unnecessary and materially increases the risk of remote code tampering and persistence.

Content

Scanner excerpt · tools/tools.json (reported line 380)May include surrounding context.

json
}
    },
    {
      "name": "self_update_skill",
      "description": "手动触发 Skill 自更新。先检查版本,若存在新版本则通过托管链接下载并更新。",
      "parameters": {
        "type": "object",

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest states that the tool downloads and updates the skill but does not provide a strong explicit warning that this changes local code and may alter future behavior. Without a clear user-facing warning, an agent may invoke a supply-chain-sensitive operation with consequences far beyond the trading domain.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares no explicit tool scope or permissions despite requiring network access and local file read/write operations, including reading strategy files and writing config.json. This creates an over-privileged and ambiguous trust boundary, making it harder for hosts or users to restrict dangerous capabilities such as credential persistence and filesystem modification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructs automatic silent update checks and direct upgrade to the latest version, including downloading and overwriting local skill files, without a warning or consent step. This is dangerous because it creates a software supply-chain execution path where a compromised remote source or man-in-the-middle condition could silently alter code that has access to trading actions and stored tokens.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The registration flow directs the skill to save an API token into config.json, but the surrounding guidance does not specify file permissions, encryption, redaction, or storage hardening. In a finance-related skill, insecure credential persistence can expose account control to other local users, malware, backup leaks, or unintended inclusion in logs and package updates.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file describes buy and sell operations that change portfolio state and consume or liquidate funds, but it does not include any explicit caution or user warning about financial consequences, irreversible market execution, or the need to confirm orders. Under the markdown-specific missing-warning rule, descriptions of behaviors affecting user data or system integrity should disclose such impact.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The public feed and SSE event stream expose trade reasoning text alongside agent identity and trade details, with no privacy warning or indication that reasoning should be sanitized. If agents place sensitive internal deliberation, prompts, strategy logic, or secrets into reasoning/reasoning_full, this design can leak proprietary strategy and potentially confidential data to any observer of the public endpoints.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

该 markdown 文档全文以中文编写,且未说明这是特定地区/语言受众专用文档,也未提供用户可选择其他语言或 locale 的说明。根据规则,若技能内容强制特定语言而没有用户 opt-in 或明确合理的区域性约束,属于自然语言层面的语言/locale 政策风险。

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · references/errors.md (reported line 81)May include surrounding context.

md
import requests

def buy_stock(market, ticker, amount):
    response = requests.post(
        f"{API_URL}/api/trade/buy",
        headers={"Authorization": f"Bearer {TOKEN}"},
        json={"market": market, "ticker": ticker, "amount": amount}

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · references/errors.md (reported line 109)May include surrounding context.

python
def register_agent(name, email, model, avatar, style):
    response = requests.post(
        f"{API_URL}/api/agents/register",
        json={
            "name": name,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The outline is written to drive the agent’s landing flow entirely in Chinese and does not provide a mechanism to detect or respect the user’s preferred language. In a financial trading context, forcing a single language can cause users to misunderstand strategy setup, trading actions, or risk disclosures, increasing the chance of unsafe or unintended decisions.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

The module docstring frames this script as a limited manual helper while directing core operational flows to the Skill conversation. However, the code goes beyond passive assistance by implementing active registration and especially code self-update, which weakens the stated boundary of responsibility in the documentation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The top-level natural-language description is written as a directive in Chinese and frames core setup and usage as occurring through the Skill dialogue, but it does not offer any language choice or opt-in. Under the policy, forcing a specific language or locale without user choice is a natural-language policy violation unless the constraint is explicitly justified.

Content

No source excerpt is available for this finding.

Tainted flow: 'download_url' from requests.get (line 278, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
81% confidence
Finding

The code performs HEAD/GET requests to a remotely supplied download_url extracted from page content, which enables network access to attacker-influenced destinations. In this specific function the request is used only to inspect headers for a version string, so impact is lower than the full updater, but it still creates an untrusted outbound fetch primitive and trusts remote redirects.

Content

Scanner excerpt · scripts/quickstart.py (reported line 235)May include surrounding context.

python
try:
        response = requests.head(download_url, allow_redirects=True, timeout=30)
    except requests.RequestException:
        response = requests.get(download_url, allow_redirects=True, stream=True, timeout=30)

    version = _extract_version_from_content_disposition(response.headers.get("content-disposition", ""))
    try:

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

A trading helper script includes a self-update routine that downloads a zip and overwrites local skill files, which is outside the minimally necessary scope for trading operations and materially increases attack surface. Because the feature modifies code on disk, any compromise of the update channel becomes a code-execution and persistence path on the host.

Content

No source excerpt is available for this finding.

Tainted flow: 'download_url' from requests.get (line 278, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
95% confidence
Finding

The script downloads an update archive from a URL derived from remote HTML metadata and then uses that content to overwrite local skill files. Although _safe_extract blocks zip-slip paths, there is no cryptographic signature or trusted allowlist validation for the update source, so a compromised hosting page, redirect target, or upstream service could deliver attacker-controlled code for persistent local compromise.

Content

Scanner excerpt · scripts/quickstart.py (reported line 286)May include surrounding context.

python
if not silent:
        print(f"⬇️  正在下载新版本 skill: {download_url}")
    response = requests.get(download_url, timeout=90)
    if response.status_code != 200:
        if not silent:
            print(f"❌ 下载更新包失败: HTTP {response.status_code}")

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest description is presented only in Chinese (AI 理财大赛工具定义) with no indication that the user may choose another language or locale. This can constitute a language-policy issue when the skill appears to impose a single language without opt-in or documented regional justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The registration tool instructs immediate persistence of a returned token to config.json but does not include an explicit security warning about storing credentials locally. This can lead to unsafe handling of a secret, accidental inclusion in logs or repositories, and broader credential exposure if config files are not protected.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill exposes update functionality that is unrelated to its core virtual-trading purpose, creating an unnecessary high-risk capability surface. A tool that can download and apply changes from a hosted link can be abused for supply-chain compromise or arbitrary skill modification if the update source or invocation path is manipulated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The self-update tool description is broad and action-oriented, making it easy for an agent or orchestrator to invoke it without understanding that it may fetch and apply code changes. Ambiguous triggering around update behavior increases the chance of unsafe autonomous execution and weakens user control over code-changing operations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This test enforces that helper text contains Chinese-language strings, which implies the underlying skill behavior is expected to present output in a fixed language. The file does not indicate any user opt-in, locale selection, or region-specific justification for this constraint.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.