Back to skill

Security audit

Cross-exchange trading platform

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real Gate CrossEx trading skill, but it needs Review because it enables live financial actions and includes an unsafe shell helper that can execute unintended commands.

Install only if you intend to let an agent work with a live Gate CrossEx account. Use read-only keys unless trading is required, disable withdrawal permissions, use IP allowlists and a low-balance subaccount, and avoid sourcing gate_crossex.sh until the eval-based curl calls and confirmation gaps are fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
gate_crossex.sh:55
Finding
Shell Command Injection Through eval-Based curl Invocation<![CDATA[ ## Vulnerability Details **File Location**: `gate_crossex.sh:55-66`, with attacker-controlled values originating at `gate_crossex.sh:70-76` and `gate_crossex.sh:114-135` **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```bash # 发送 GET 请求 api_get() { local endpoint="$1" local params="$2" local url="${BASE_URL}${API_PREFIX}${endpoint}" if [ -n "$params" ]; then url="${url}?${params}" fi local headers=$(generate_signature "GET" "${API_PREFIX}${endpoint}" "$params" "") eval curl -s -X GET \"${url}\" $headers } # 发送 POST 请求 api_post() { local endpoint="$1" local data="$2" local url="${BASE_URL}${API_PREFIX}${endpoint}" local headers=$(generate_signature "POST" "${API_PREFIX}${endpoint}" "" "$data") eval curl -s -X POST \"${url}\" $headers -d \"${data}\" } ``` Attacker-controlled values can reach these functions through exported public functions: ```bash get_symbols() { local symbols="$1" local params="" if [ -n "$symbols" ]; then params="symbols=${symbols}" fi echo "📊 查询币对信息..." api_get "/rule/symbols" "$params" | jq '.' } ``` ```bash transfer_funds() { local currency="$1" local amount="$2" local from_account="$3" local to_account="$4" local data=$(cat <<EOF { "currency": "${currency}", "amount": "${amount}", "from": "${from_account}", "to": "${to_account}" } EOF ) echo "💸 资金划转: ${amount} ${currency} 从 ${from_account} 到 ${to_account}..." api_post "/wallet/transfers" "$data" | jq '.' } ``` ### Technical Analysis The script constructs curl commands as strings and executes them with `eval`. Unlike an ordinary command invocation, `eval` asks the shell to parse the generated command a second time. Values supplied through `symbols`, `currency`, `amount`, `from_account`, or `to_account` are embedded in that generated shell source. Embedded quotation marks, command substitutions, sepa ...[truncated 1990 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove every use of `eval`. 2. Construct curl arguments with a Bash array so each value remains a single argument: ```bash api_get() { local endpoint="$1" local params="$2" local url="${BASE_URL}${API_PREFIX}${endpoint}" local timestamp signature validate_endpoint "$endpoint" || return 1 if [[ -n "$params" ]]; then url="${url}?${params}" fi timestamp="$(date +%s)" signature="$(generate_signature_value \ "GET" "${API_PREFIX}${endpoint}" "$params" "" "$timestamp")" || return 1 curl_args=( --silent --show-error --fail-with-body --request GET --header "KEY: ${API_KEY}" --header "Timestamp: ${timestamp}" --header "SIGN: ${signature}" --header "Accept: application/json" --header "Content-Type: application/json" "$url" ) curl "${curl_args[@]}" } ``` 3. Use `curl --get --data-urlencode` rather than manually concatenating untrusted query parameters. 4. Build transfer JSON with a serializer rather than a heredoc: ```bash data="$(jq -n \ --arg currency "$currency" \ --arg amount "$amount" \ --arg from "$from_account" \ --arg to "$to_account" \ '{currency: $currency, amount: $amount, from: $from, to: $to}')" ``` 5. Validate symbols, currencies, account identifiers, and amounts against strict allowlists or documented formats. 6. Keep API endpoints internal and allowlist all supported endpoint paths. 7. Add regression tests containing quotation marks, command substitutions, separators, whitespace, and newline characters to verify that inputs cannot become shell syntax. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
gate_crossex.sh:38
Finding
API Secret Passed to OpenSSL Through Process Arguments<![CDATA[ ## Vulnerability Details **File Location**: `gate_crossex.sh:38` **Vulnerability Type**: Sensitive credential exposure through command-line arguments **Risk Level**: Medium ### Vulnerable Code ```bash # 生成 HMAC-SHA512 签名 local signature=$(printf "%b" "$sign_string" | openssl dgst -sha512 -hmac "$API_SECRET" -hex | awk '{print $2}') ``` ### Technical Analysis The Gate API secret is supplied to OpenSSL as the argument following `-hmac`. Command-line arguments may be exposed through process inspection mechanisms such as process listings or procfs, depending on the operating system's access controls. Although the OpenSSL process is short-lived, API operations repeatedly invoke it, creating recurring opportunities for a local observer to capture the secret. The secret grants the ability to create valid HMAC signatures and is more sensitive than the request signatures transmitted to the declared API. This exposure is not necessary for the Skill's declared functionality. HMAC generation can be performed without placing the key in a child process's argument vector. ### Attack Path 1. The victim runs an authenticated function such as `get_account` or `transfer_funds`. 2. `generate_signature` launches OpenSSL with the plaintext API secret in its process arguments. 3. A local process with sufficient process-inspection access monitors command lines during repeated API operations. 4. The monitoring process captures the value following the `-hmac` option. 5. The attacker uses the key and corresponding API identifier to generate valid Gate API signatures. 6. The attacker performs any account, trading, or transfer operation allowed by that API key. This attack requires local process-observation access. Its feasibility depends on host configuration, procfs restrictions, container isolation, and whether other workloads share the same user or execution boundary. ### Impact Assessment Disclosure of the secret compromises the authentication boundary of the Gate ...[truncated 534 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not pass secrets through command-line arguments. 2. Prefer an in-process cryptographic implementation, such as a small Python helper using the standard-library `hmac` and `hashlib` modules. 3. If a subprocess must be used, select an interface that accepts key material through a protected file descriptor or another mechanism not exposed in argv. 4. Avoid temporary files for secret storage. If unavoidable, create them with restrictive permissions, prevent symlink attacks, and delete them reliably. 5. Run the Skill in an isolated user or container context where unrelated processes cannot inspect it. 6. Configure Gate API keys with: - Only the permissions required for the intended operation. - Withdrawal disabled. - An IP allowlist. - A dedicated low-balance subaccount. 7. Rotate the API secret after replacing the signing implementation if the script has been used on a shared or potentially compromised host. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Unbounded Third-Party Dependency Version<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1` **Vulnerability Type**: Unpinned dependency and non-reproducible installation **Risk Level**: Low ### Vulnerable Code ```text requests>=2.31.0 ``` The README also recommends an unconstrained installation: ```bash pip install requests ``` ### Technical Analysis The lower-bound-only requirement allows installation of any future `requests` release that satisfies the version comparison. There is no lockfile or integrity hash to bind installation to a reviewed artifact. No malicious or currently known-vulnerable package was identified in the audited files. The risk is that future installations can resolve to code that was not part of this review, reducing reproducibility and weakening supply-chain controls. Dependency resolution can also vary over time or between environments due to transitive dependency changes. ### Attack Path 1. A user installs the project dependencies at a later date. 2. The package resolver selects a newer, previously unaudited release of `requests` or one of its transitive dependencies. 3. If that selected artifact is compromised, malicious installation or runtime behavior executes in the user's environment. 4. The compromised dependency may access the Skill process's API credentials, network traffic, and files available to the current user. This is a prospective supply-chain hardening issue; the audit found no evidence that the currently named `requests` package is malicious. ### Impact Assessment A compromised dependency executes with the same privileges as the Python process importing it. In this Skill's intended environment, that scope could include: - Access to Gate API credentials stored in environment variables. - Modification or interception of authenticated API requests. - Reading files accessible to the current user. - Arbitrary outbound network communication. - Arbitrary code execution under the invoking account. Actual impact depends on which ar ...[truncated 54 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the dependency to a reviewed version rather than using only a lower bound. 2. Generate a lockfile that includes all transitive dependencies. 3. Require cryptographic hashes during installation, for example through a hash-locked requirements file and `pip install --require-hashes`. 4. Install only from trusted package indexes over authenticated TLS. 5. Use automated dependency monitoring and update pinned versions after review and testing. 6. Ensure the README uses the project's locked requirements rather than recommending a separate unconstrained installation command. ]]>
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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (17)

Credential Access

High
Category
Privilege Escalation
Content
config_paths:
  - ~/.openclaw/credentials/gate.json
  - ~/.gate/credentials.json

binaries:
  - openssl: 签名加密
Confidence
80% confidence
Finding
The skill explicitly relies on locally stored API credentials in predictable filesystem paths and environment variables, while also enabling networked trading actions. In an agent setting, encouraging plaintext secret storage and automatic credential discovery increases the blast radius if the skill or surrounding tooling is compromised, because exchange API keys can authorize trades and internal transfers.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
POST /orders

# 撤单
DELETE /orders

# 改单
PUT /orders/{order_id}
Confidence
86% confidence
Finding
The skill exposes destructive trade operations such as DELETE /orders within a generic unified trading interface. In an agentic environment, if tool parameters are influenced by ambiguous prompts, automation errors, or prompt injection from external market data/tasks, the skill could cancel legitimate orders or alter live positions, causing direct financial loss.

Missing User Warnings

High
Confidence
99% confidence
Finding
The script uses eval to execute curl commands assembled from variables that include endpoint, query parameters, headers, and POST data. If any of these values contain shell metacharacters or crafted quoting, an attacker could achieve command injection and execute arbitrary shell commands in the user's environment, which is especially dangerous because API secrets are already loaded in the same process.

Context-Inappropriate Capability

High
Confidence
95% confidence
Finding
The script exposes a fund-transfer primitive that can move assets between accounts with no confirmation prompt, policy guardrails, allowlist, or dry-run mode. In an agent or automation context, this creates a high-risk financial action surface where mistaken inputs or downstream prompt/parameter injection could trigger unauthorized or unintended transfers.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The README advertises account management, fund transfers, order placement, cancellation, and swap capabilities, but it does not clearly warn that these actions can move funds, open positions, or cause irreversible financial loss if invoked unintentionally. In a trading skill, missing prominent account-impact warnings increases the chance that users or downstream agents treat dangerous operations as routine API calls and execute them without adequate confirmation.

External Transmission

Medium
Category
Data Exfiltration
Content
### 基础信息

- **实盘交易**: `https://api.gateio.ws/api/v4/crossex`

### 主要功能模块
Confidence
50% 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
### 基础信息

- **实盘交易**: `https://api.gateio.ws/api/v4/crossex`

### 主要功能模块
Confidence
50% 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
"to": "BINANCE"
}

response = requests.post(
    f"{host}{prefix}/wallet/transfers",
    headers=headers,
    json=transfer_data
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# 设置正确的文件权限
chmod 600 ~/.openclaw/credentials/gate.json
```

### 4. 最小资金原则
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Context-Inappropriate Capability

Medium
Confidence
85% confidence
Finding
No manifest is available, so the skill's intended scope is unknown. The code explicitly reads API key and secret values from environment variables and refuses to run without them, which is a sensitive capability not justified by any stated purpose in the provided context.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The script reads API credentials from environment variables and uses them to generate authenticated request headers for outbound HTTPS requests. While it errors if the variables are missing, it does not clearly warn users that the loaded shell functions will access credentials and transmit authenticated account and transfer requests to an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
local headers=$(generate_signature "GET" "${API_PREFIX}${endpoint}" "$params" "")

    eval curl -s -X GET \"${url}\" $headers
}

# 发送 POST 请求
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The README content is written entirely in Chinese, including usage guidance and warnings, with no indication that users may choose another language. Under the policy, forcing a specific language without user opt-in is a natural-language policy issue unless the locale restriction is clearly documented and justified.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
This markdown file presents the skill description, configuration steps, warnings, and operational guidance only in Chinese. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation when no alternative locale or language choice is provided.

Intent-Code Divergence

Low
Confidence
92% confidence
Finding
The inline example comment says '查询 BTC 价格' (query BTC price), but get_symbols calls the /rule/symbols endpoint and is documented elsewhere as querying symbol information. This is an active documentation mismatch that could mislead users about the function's intent and returned data.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.31.0
Confidence
97% confidence
Finding
The dependency is specified as `requests>=2.31.0`, which allows any newer release to be installed and makes builds non-reproducible. This can unintentionally pull in a vulnerable or breaking version later, and it prevents reviewers from verifying exactly which package version the skill will use.

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
90% confidence
Finding
Because `requests` is not pinned to a specific version, it is impossible to determine from this manifest whether installation will resolve to a version affected by one of the known advisories for that package. This uncertainty weakens supply-chain review and could permit deployment of a vulnerable release depending on resolver behavior and environment state.