Back to skill

Security audit

ChainUp Spot

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real trading/account API wrapper, but it gives an agent high-impact financial authority with an overridable API destination and a documented confirmation bypass.

Install only if you are comfortable letting an agent use ChainUp API credentials for account and trading operations. Use least-privilege keys, avoid transfer/withdraw permissions unless required, keep `--no-confirm-gate` disabled, and do not allow arbitrary `--base-url` values or inherited credentials to be sent to unverified hosts.

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

Error
Location
scripts/chainup_api.py:479
Finding
Arbitrary API Endpoint Can Receive Automatically Loaded Exchange Credentials<![CDATA[ ## Vulnerability Details **File Location**: `scripts/chainup_api.py:215-238` and `scripts/chainup_api.py:479-503` **Vulnerability Type**: Arbitrary credential destination and missing transport validation **Risk Level**: High ### Vulnerable Code ```python def request( self, method: str, path: str, *, signed: bool, query: Optional[Dict[str, Any]] = None, body: Optional[Dict[str, Any]] = None, ) -> Dict[str, Any]: method_u = method.upper() query = query or {} query = {k: v for k, v in query.items() if v is not None} body = {k: v for k, v in (body or {}).items() if v is not None} query_str = urlencode(query, doseq=True) request_path = path + (f"?{query_str}" if query_str else "") url = urljoin(self.cfg.base_url.rstrip("/") + "/", request_path.lstrip("/")) payload_bytes = None body_str_for_sign = None if method_u != "GET": body_str_for_sign = self._json_dumps_compact(body) if body else "{}" payload_bytes = body_str_for_sign.encode("utf-8") headers = { "Content-Type": "application/json", "admin-language": "en_US", "User-Agent": USER_AGENT, } if signed: ts_ms = str(int(time.time() * 1000)) headers["X-CH-APIKEY"] = self.cfg.api_key headers["X-CH-TS"] = ts_ms headers["X-CH-SIGN"] = self._sign( ts_ms, method_u, request_path, body_str_for_sign ) req = Request(url=url, data=payload_bytes, method=method_u, headers=headers) try: with urlopen(req, timeout=self.cfg.timeout) as resp: ``` ```python def _build_config(args: argparse.Namespace) -> ChainUpConfig: tools_cfg = _load_tools_config() base_url = ( args.base_url or tools_cfg.get("BASE_URL", "") or os.getenv("CHAINUP_BASE_URL", "") ) api_key = ( args.api_key or tools_cfg.get("API_KEY", "") or os.getenv("CHAINUP_API_KEY", "") ) secret_key = ( ...[truncated 3411 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Require HTTPS** - Parse the URL with `urllib.parse.urlparse`. - Reject any scheme other than `https`. - Reject URLs containing user information, fragments, or unexpected path components. 2. **Restrict credential destinations** - Maintain an explicit allowlist of approved exchange hostnames. - Compare normalized hostnames exactly; do not use suffix or substring matching. - Consider certificate or public-key pinning for tightly controlled deployments. 3. **Bind credentials to an origin** - Store each API key and secret together with its approved base URL. - Refuse to use credentials when the selected scheme, hostname, or port differs from the bound origin. 4. **Prevent unsafe source mixing** - If `--base-url` is provided, do not silently combine it with credentials from `/root/TOOLS.md` or environment variables. - Require an explicit, security-focused approval before sending inherited credentials to a newly selected origin. - Prefer named configuration profiles containing the URL and credentials as one atomic configuration unit. 5. **Validate before signing** - Perform all destination checks before constructing authentication headers or signatures. - Fail closed if URL parsing or hostname validation is ambiguous. 6. **Apply least-privilege exchange permissions** - Use read-only API keys for query-only workflows. - Separate trading and transfer credentials. - Disable withdrawal or transfer permissions unless strictly required. - Use exchange-side IP allowlisting where available. 7. **Add regression tests** - Verify that HTTP URLs are rejected. - Verify that unapproved hosts are rejected. - Verify that a CLI URL override cannot inherit credentials belonging to another origin. - Verify handling of hostname confusion, alternate ports, user-information components, redirects, and malformed URLs. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
- Any action that affects balances, even if it may not fill immediately, is still treated as a live balance-changing action. This includes but is not limited to limit orders, batch orders, cancellations, transfers, margin orders, and margin cancellations.
- Query actions can execute directly, including but not limited to balance queries, order queries, trade history queries, market data queries, and open-order queries.
- Precision prechecks are mandatory before order confirmation so the script does not send prices or quantities that exceed symbol precision to the live gateway.
- If the user explicitly requests to bypass confirmation, `--no-confirm-gate` may be used. This is high risk and should only be used with explicit user authorization.
- Never print full credentials in the terminal or reply. If the script throws an error that could expose secrets, summarize the failure rather than copying the raw sensitive output.

## Examples
Confidence
97% confidence
Finding
This is a direct tool-parameter abuse risk: the skill advertises a flag that disables the confirmation gate protecting high-risk signed API calls. Because the script is the mandatory execution path for real trading/account actions, a parameter that suppresses approval can be abused to convert a guarded workflow into an unguarded one with immediate financial impact.

Missing User Warnings

High
Confidence
96% confidence
Finding
The example shows a live MARKET SELL order against a real trading endpoint with no warning that executing it can immediately sell user assets. In an agent-skill context, runnable examples may be copied verbatim or automated, so omission of a prominent caution materially increases the risk of unintended financial loss.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
help="For mutating requests, must be exactly CONFIRM when required",
    )
    parser.add_argument(
        "--no-confirm-gate",
        action="store_true",
        help="Disable CONFIRM gate for mutating requests",
    )
Confidence
96% confidence
Finding
This is a true parameter-abuse risk because an agent or caller can supply --no-confirm-gate to suppress the only local guard intended to prevent unreviewed execution of dangerous trading operations. Since the tool supports signed order placement, cancellation, and asset transfer, a malicious prompt, compromised workflow, or accidental misuse could directly trigger unauthorized financial transactions.

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill explicitly instructs the agent to read local files for credentials (`/root/TOOLS.md`), access environment variables, and make authenticated network requests, but it declares no tool scope or permission boundaries. In an agent system, this creates an unnecessary privilege gap: the skill can access secrets and external endpoints without machine-readable constraints, increasing the chance of credential misuse or unintended execution.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The activation criteria are very broad, causing the skill to trigger on many generic trading/account phrases and then push the agent to execute the script quickly with minimal explanation. In a financial trading context, overbroad triggering increases the chance of the wrong skill being invoked and acting on ambiguous requests, which can lead to unintended authenticated API calls.

Natural-Language Policy Violations

Medium
Confidence
84% confidence
Finding
The skill states that built-in common headers include `admin-language`, which implies a locale/language choice is being set automatically. The file does not indicate that the user can choose the language value or that the locale constraint is justified, creating a potential language/locale policy issue.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- Any action that affects balances, even if it may not fill immediately, is still treated as a live balance-changing action. This includes but is not limited to limit orders, batch orders, cancellations, transfers, margin orders, and margin cancellations.
- Query actions can execute directly, including but not limited to balance queries, order queries, trade history queries, market data queries, and open-order queries.
- Precision prechecks are mandatory before order confirmation so the script does not send prices or quantities that exceed symbol precision to the live gateway.
- If the user explicitly requests to bypass confirmation, `--no-confirm-gate` may be used. This is high risk and should only be used with explicit user authorization.
- Never print full credentials in the terminal or reply. If the script throws an error that could expose secrets, summarize the failure rather than copying the raw sensitive output.

## Examples
Confidence
95% confidence
Finding
The presence of the `--no-confirm-gate`/`--no-confirm` bypass enables autonomous execution of sensitive financial actions without the normal user acknowledgment step. Because this skill is designed to place orders and move assets via signed API requests, any confirmation bypass significantly raises the risk of unintended trades, cancellations, or transfers.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- Any action that affects balances, even if it may not fill immediately, is still treated as a live balance-changing action. This includes but is not limited to limit orders, batch orders, cancellations, transfers, margin orders, and margin cancellations.
- Query actions can execute directly, including but not limited to balance queries, order queries, trade history queries, market data queries, and open-order queries.
- Precision prechecks are mandatory before order confirmation so the script does not send prices or quantities that exceed symbol precision to the live gateway.
- If the user explicitly requests to bypass confirmation, `--no-confirm-gate` may be used. This is high risk and should only be used with explicit user authorization.
- Never print full credentials in the terminal or reply. If the script throws an error that could expose secrets, summarize the failure rather than copying the raw sensitive output.

## Examples
Confidence
95% confidence
Finding
The presence of the `--no-confirm-gate`/`--no-confirm` bypass enables autonomous execution of sensitive financial actions without the normal user acknowledgment step. Because this skill is designed to place orders and move assets via signed API requests, any confirmation bypass significantly raises the risk of unintended trades, cancellations, or transfers.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The prompt instructs the skill to always include `admin-language=en_US`, which imposes a specific language/locale choice. The policy allows locale constraints only when user choice or a justified region-specific need is documented, neither of which appears here.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
This markdown file includes concrete examples that use `API_KEY`, `SECRET_KEY`, HMAC signing, and account/order endpoints, which imply transmission of sensitive credentials and potentially account or trading data. Under the markdown-specific warning criterion, the document does not include any explicit caution about protecting credentials, using non-production keys, or understanding the impact of sending authenticated requests.

External Transmission

Medium
Category
Data Exfiltration
Content
PAYLOAD="${TS}${METHOD}${PATH}${BODY}"
SIGN=$(printf '%s' "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET_KEY" | awk '{print $2}')

curl -sS -X POST "${BASE_URL}${PATH}" \
  -H "Content-Type: application/json" \
  -H "X-CH-APIKEY: ${API_KEY}" \
  -H "X-CH-TS: ${TS}" \
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
help="For mutating requests, must be exactly CONFIRM when required",
    )
    parser.add_argument(
        "--no-confirm-gate",
        action="store_true",
        help="Disable CONFIRM gate for mutating requests",
    )
Confidence
94% confidence
Finding
The script includes a built-in bypass for its safety interlock: passing --no-confirm-gate disables the explicit CONFIRM requirement for mutating actions such as placing orders, cancelling orders, and transferring assets. In a trading skill, this weakens defense-in-depth against accidental or agent-driven state-changing operations and enables autonomous execution of financially sensitive actions with no human acknowledgement.

Scope Creep

Low
Category
Excessive Agency
Content
## Safety Rules

- All live balance-changing actions (place order, cancel order, transfer) require the user to send `Confirm` manually before execution, then use `--confirm CONFIRM`.
- Any action that affects balances, even if it may not fill immediately, is still treated as a live balance-changing action. This includes but is not limited to limit orders, batch orders, cancellations, transfers, margin orders, and margin cancellations.
- Query actions can execute directly, including but not limited to balance queries, order queries, trade history queries, market data queries, and open-order queries.
- Precision prechecks are mandatory before order confirmation so the script does not send prices or quantities that exceed symbol precision to the live gateway.
- If the user explicitly requests to bypass confirmation, `--no-confirm-gate` may be used. This is high risk and should only be used with explicit user authorization.
Confidence
70% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Scope Creep

Low
Category
Excessive Agency
Content
## Safety Rules

- All live balance-changing actions (place order, cancel order, transfer) require the user to send `Confirm` manually before execution, then use `--confirm CONFIRM`.
- Any action that affects balances, even if it may not fill immediately, is still treated as a live balance-changing action. This includes but is not limited to limit orders, batch orders, cancellations, transfers, margin orders, and margin cancellations.
- Query actions can execute directly, including but not limited to balance queries, order queries, trade history queries, market data queries, and open-order queries.
- Precision prechecks are mandatory before order confirmation so the script does not send prices or quantities that exceed symbol precision to the live gateway.
- If the user explicitly requests to bypass confirmation, `--no-confirm-gate` may be used. This is high risk and should only be used with explicit user authorization.
Confidence
70% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The file instructs use of `admin-language: en_US` as a required header and repeats that locale in examples, but does not offer alternatives or explain why English (US) is required. This is a natural-language locale policy issue because it forces a specific locale without opt-in or documented necessity.

Static analysis

No suspicious patterns detected.