Back to skill

Security audit

Opinion Skill

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Opinion trading helper, but it asks users to run mutable remote code and handle private-key trading in ways that need Review before installation.

Install only if you are comfortable reviewing and pinning the external repository, replacing curl-to-bash with a verified Bun install, using a non-root working directory, and protecting the .env private key. Do not fund or approve a wallet you cannot afford to risk, and be aware that some market and position queries use an unencrypted HTTP API that can expose or alter decision-critical data.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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 (5)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:24
Finding

Unverified Remote Bun Installer Is Piped Directly into a Shell

Content
View full analysis
/dev/null 2>&1 && echo "bun $(bun --version)" || { curl -fsSL https://bun.sh/install | bash && source ~/.bashrc; } ``` ``` ### Technical Analysis The installation instruction retrieves a mutable script from `https://bun.sh/install` and pipes it directly into `bash`. The response is executed before the user can inspect it, and the command does not pin an installer version or validate a checksum or cryptographic signature. Although installing Bun is related to the declared functionality, executing an unverified remote response is not the minimum privilege or safest mechanism necessary to install the runtime. The effective code executed on the machine can change after the Skill has been reviewed. The risk applies even when the current endpoint is legitimate: compromise of the hosting service, distribution infrastructure, DNS or TLS trust chain, or installer publishing account could turn this command into arbitrary code execution. ### Attack Path 1. A user follows the documented prerequisite instructions. 2. Bun is not already installed, causing the fallback branch to run. 3. `curl` downloads the current response from `bun.sh`. 4. The response is passed directly to `bash` without integrity verification. 5. A compromised or malicious response executes with the privileges of the user running the command. 6. The payload can inspect files, access environment variables, modify the host, or steal wallet credentials subsequently stored on the system. ### Impact Assessment The remote payload obtains arbitrary command execution with the invoking user's privileges. Because the documentation consistently uses `/root/opinionskills`, execution as root is plausible. In that case, the payload could obtain full system control, ...[truncated 136 chars]
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:7
Finding

Mutable Personal Git Repository Is Cloned and Later Executed Without Integrity Verification

Content
View full analysis
/dev/null && echo "scripts ready" || { echo "scripts missing, cloning..."; git clone https://github.com/Yuandiaodiaodiao/opinion-skill.git /root/opinionskills; } ``` ``` The cloned scripts are subsequently executed through documented commands such as: ```bash bun run scripts/enable-trading.ts bun run scripts/buy.ts --market --token --price 0.45 --amount 10 ``` ### Technical Analysis The fallback instructions clone the mutable default branch of a personal GitHub repository. No commit hash, signed tag, archive checksum, or other integrity control binds the downloaded repository to the version that was audited. The existence check verifies only that `scripts/config.ts` is present. It does not verify the origin or integrity of any script. A repository takeover, account compromise, force-push, or malicious future commit could therefore replace the reviewed code with arbitrary TypeScript. The documented workflow later places wallet credentials in `/root/opinionskills/.env` and executes the cloned scripts with Bun. This gives changed repository code direct access to those credentials and the host user's permissions. ### Attack Path 1. The expected local `scripts` directory or `config.ts` file is absent. 2. The fallback command clones the current default branch from the remote repository. 3. The user creates `.env` containing a wallet private key and API credentials. 4. The user runs one of the cloned TypeScript scripts with Bun. 5. Malicious code introduced through repository compromise executes locally. 6. It can r ...[truncated 525 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/config.ts:8
Finding

Market and Wallet Data Are Transmitted over Unencrypted HTTP

Content
View full analysis
(path: string, params?: Record): Promise { const url = new URL(path, OPINION_API_HOST); if (params) { for (const [k, v] of Object.entries(params)) { if (v !== undefined && v !== null) url.searchParams.set(k, String(v)); } } const resp = await fetch(url.toString(), { signal: AbortSignal.timeout(30000) }); if (!resp.ok) throw new Error(`API ${resp.status}: ${resp.statusText}`); return resp.json() as Promise; } ``` This shared wrapper is used by market, price, order-book, trade, and position-query scripts. For example, `scripts/positions.ts:6-7` sends a wallet address in the URL: ```ts async function getPositions(address: string, limit: number, json: boolean): Promise { const resp = await apiFetch(`/api/user/positions/${address}`, { limit, includeConditionId: "true" }); ``` ### Technical Analysis The API host uses plain HTTP rather than HTTPS. Requests and responses therefore lack transport confidentiality and authenticated integrity. Network observers can inspect wallet addresses, search terms, market identifiers, and asset identifiers. An active network attacker can also modify returned market details, positions, prices, or order-book data. These outbound requests are necessary for the Skill's declared query functionality, and the audited first-party code does not attach the wallet private key to this endpoint. However, unencrypted transport is not necessary and does not satisfy least-privilege handling of wallet-related information. The integrity risk is financially significant because `buy.ts` and `sell.ts` retrieve and display prices through thi ...[truncated 1002 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/market-cache.ts:42
Finding

Unauthenticated Search Path Implicitly Reads and Transmits an Ambient API Key

Content
View full analysis
): Promise { // path 是相对路径如 "/market", 拼接到 OPENAPI_BASE 末尾 const base = OPENAPI_BASE.endsWith("/") ? OPENAPI_BASE : OPENAPI_BASE + "/"; const url = new URL(path.replace(/^\//, ""), base); if (params) { for (const [k, v] of Object.entries(params)) { if (v !== undefined && v !== null) url.searchParams.set(k, String(v)); } } const headers: Record = {}; const apiKey = process.env.API_KEY; if (apiKey) headers["apikey"] = apiKey; const resp = await fetch(url.toString(), { headers, signal: AbortSignal.timeout(30000) }); if (!resp.ok) throw new Error(`OpenAPI ${resp.status}: ${resp.statusText}`); return resp.json(); } ``` The cache function is automatically reached by the search workflow in `scripts/search.ts:42-50`: ```ts const [apiPromise, cachePromise] = [ apiFetch("/api/markets/search", { q: keyword, limit }).catch(() => null), getMarkets(refresh).then(m => fuzzySearch(m, keyword, limit)).catch(() => [] as SearchResult[]), ]; const [apiResp, cacheResults] = await Promise.all([apiPromise, cachePromise]); ``` ### Technical Analysis The documentation describes search and market-data scripts as requiring no environment variables. Nevertheless, the market-cache implementation automatically reads the generic ambient variable `API_KEY` and sends it to `https://openapi.opinion.trade` whenever that variable exists. The destination is consistent with the declared Opinion market functionality, and there is no evidence that the code sends the private key. However, implicit use of a generic environment variable exceeds the minimum privilege needed for the advertised unauthenticated search path. A key intended for another service or a differ ...[truncated 1081 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
package.json:21
Finding

Trading Dependencies Are Mutable and Lack a Lockfile

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (27)

External Script Fetching

High
Category
Supply Chain
Confidence
97% confidence
Finding

The skill instructs users to execute a remote installation script via 'curl ... | bash', which grants arbitrary code from an external server immediate shell execution on the host. Because this skill also operates in a sensitive context involving trading credentials and private keys, compromise of the runtime environment could lead to theft of wallet secrets, tampering with trades, or full host compromise.

Content

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

  1. 安装 bun:
    bash
    command -v bun >/dev/null 2>&1 && echo "bun $(bun --version)" || { curl -fsSL https://bun.sh/install | bash && source ~/.bashrc; }
    
  2. 创建 .env 文件:
    text

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

执行交易操作前,先确认 .env 是否已配置:

bash
test -f /root/opinionskills/.env && grep -q "PRIVATE_KEY=0x" /root/opinionskills/.env && echo "Trading credentials configured" || echo "WARNING: .env not configured — only market data queries are available. To trade, create /root/opinionskills/.env with PRIVATE_KEY, MULTI_SIG_ADDRESS, and API_KEY."

如果用户要求下单但 .env 未配置,不要执行交易脚本,而是提示用户先配置环境变量。

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
bun run scripts/price.ts <assetId> [<assetId2> ...] [--json] # 查询价格

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
bun run scripts/orderbook.ts <assetId> [--json] # 查看订单簿

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
bun run scripts/orderbook.ts <assetId> [--json] # 查看订单簿

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
bun run scripts/trades.ts <assetId> [--limit <n>] [--filter all|taker|maker] [--json] # 成交记录

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
bun run scripts/top-markets.ts [--tag volume|txn] [--window 1h|4h|24h] [--json] # 热门市场

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/sdk-config.ts (reported line 24)May include surrounding context.

ts
function getClient(): Client {
  if (!PRIVATE_KEY) {
    console.error("Error: set PRIVATE_KEY in .env");
    process.exit(1);
  }
  if (!MULTI_SIG_ADDRESS) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/sdk-config.ts (reported line 28)May include surrounding context.

ts
function getClient(): Client {
  if (!PRIVATE_KEY) {
    console.error("Error: set PRIVATE_KEY in .env");
    process.exit(1);
  }
  if (!MULTI_SIG_ADDRESS) {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/sdk-config.ts (reported line 32)May include surrounding context.

ts
function getClient(): Client {
  if (!PRIVATE_KEY) {
    console.error("Error: set PRIVATE_KEY in .env");
    process.exit(1);
  }
  if (!MULTI_SIG_ADDRESS) {

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The natural-language instructions throughout the skill file are presented exclusively in Chinese, which effectively forces a specific language for users. The policy allows locale constraints only when users are given a choice or when the constraint is clearly documented and justified, neither of which appears here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's natural-language interface is presented in Chinese only, including the purpose and usage guidance. This imposes a specific language on users without any opt-in, alternative locale, or documented region-specific justification, which matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The comments are written entirely in Chinese and indicate intended usage only in that language context, with no indication that users may choose another language or locale. Per the policy, forcing a specific language without opt-in can be a natural-language policy violation unless clearly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code file contains natural-language instructions in comments that force a specific language context for readers. The policy calls for flagging language or locale constraints when the skill does not offer user opt-in or justify the restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This TypeScript file contains natural-language comments and user-facing output in Chinese, such as the top-level file description and cache-status messaging. Because the skill does not offer a language option or justify that it is intentionally region-specific, it violates the language/locale policy for natural-language content.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

With no manifest available, the skill's intended scope is unknown, so accessing process environment for credentials is an extra capability that is not justified by any declared purpose. The rest of the file is primarily market-data caching and fuzzy search logic, making secret retrieval a distinct capability requiring explicit intent declaration.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The file loads highly sensitive values from environment variables and then exports them module-wide, including the private key and API key. Exporting raw credentials increases the chance that other parts of the codebase accidentally log, leak, or misuse them, especially in a trading script context where the private key directly authorizes on-chain actions.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This TypeScript file contains natural-language comments and usage guidance in Chinese only, such as the file description and usage instructions. Under the policy, forcing a specific language without user opt-in or documented justification is a locale/language policy violation.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 22)May include surrounding context.

json
"enable-trading": "bun run scripts/enable-trading.ts"
  },
  "dependencies": {
    "@opinion-labs/opinion-clob-sdk": "^0.5.3",
    "axios": "^1.7.0"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · package.json (reported line 23)May include surrounding context.

json
},
  "dependencies": {
    "@opinion-labs/opinion-clob-sdk": "^0.5.3",
    "axios": "^1.7.0"
  }
}

Unverifiable Dependency: axios has 16 known advisory(ies) (CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +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
79% confidence
Finding

The manifest references axios with a non-exact version and no visible lockfile context, while axios has multiple published advisories including SSRF- and proxy-related issues in some versions. In a trading skill that likely makes outbound API requests and may handle credentials or network configuration, an unresolved vulnerable axios version could expose requests, tokens, or routing controls if a susceptible release is installed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This TypeScript file performs an outbound HTTP request via fetch, which can transmit query parameters derived from caller-supplied data to an external host. There is no visible confirmation prompt, user-facing log, or explanatory comment warning that request parameters may be sent over the network.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The interface comment documents marketType values as 0 and 1 only, yet the fetch call uses marketType: 2 with an inline comment claiming it means all types. This is an active documentation contradiction about the meaning of a key request parameter, which can mislead reviewers about what data is actually retrieved.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code sends the user-provided wallet address to /api/user/positions/${address} and then submits derived asset IDs to a batch markets endpoint. Although the script name suggests position lookup, there is no explicit disclosure in comments, help text, or runtime output that external API calls will transmit portfolio-related identifiers and data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file’s user-facing natural language is exclusively Chinese in the header comments and usage description, with no indication of alternative language support or user choice. Under the stated policy, forcing a specific language without opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/market-cache.ts:52