T09 · Insecure Skill Coding Practices
- Location
SKILL.md:86- Finding
Persistent plaintext storage of trading API credentials
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Bybit trading skill is coherent and not deceptive, but it deserves review because it stores and uses live trading credentials for real-money account actions.
Install only if you are comfortable giving an AI tool Bybit Read+Trade authority. Use testnet first, use a dedicated limited-balance sub-account, never enable withdrawals, bind the key to an IP where possible, prefer a secure secret store over .env or shell profile files, and review every mainnet confirmation card before typing CONFIRM.
SKILL.md:86Persistent plaintext storage of trading API credentials
SKILL.md:251API secret exposed through command-line HMAC invocation
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OpenClaw — use .env file:
# ~/.openclaw/.env
BYBIT_API_KEY=your_api_key
BYBIT_API_SECRET=your_secret_key
BYBIT_ENV=testnet
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OpenClaw — use .env file:
# ~/.openclaw/.env
BYBIT_API_KEY=your_api_key
BYBIT_API_SECRET=your_secret_key
BYBIT_ENV=testnet
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
OpenClaw — use .env file:
# ~/.openclaw/.env
BYBIT_API_KEY=your_api_key
BYBIT_API_SECRET=your_secret_key
BYBIT_ENV=testnet
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
**On first use:** Check if `BYBIT_API_KEY` and `BYBIT_API_SECRET` are set. If missing, tell the user which variable is absent and show the setup instructions above. Do NOT proceed until both variables are present. Do NOT ask the user to paste keys in the conversation.
**Display rules** (never show full credentials):
- API Key: show first 5 + last 4 characters (e.g., `AbCdE...x1y2`)
- Secret Key: show last 5 only (e.g., `***...vWxYz`)
- **Code blocks (CRITICAL)**: NEVER include raw API Key or Secret Key values in generated code, scripts, or curl examples — even if the actual values are available in environment variables or session context. ALWAYS use `$BYBIT_API_KEY` / `$BYBIT_API_SECRET` (or `${API_KEY}` / `${SECRET_KEY}`) as variable references. This applies to ALL output formats including bash, python, and JSON. Violation of this rule is a **security incident**.
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).
- **Trading Bot**: Bot API uses `status_code`/`debug_msg` response format (NOT `retCode`/`retMsg`). **Always call `validate-input` (spot grid) or `validate` (futures grid) before creation** — this returns acceptable parameter ranges and catches errors early. DCA: max **5 trading pairs** per bot; if user requests more, ask them to choose up to 5.
- **Alpha Trade**: Uses a **quote-then-execute** model — always call `/v5/alpha/trade/quote` first. Token codes use `CEX_<id>` (payment tokens like USDT) and `DEX_<id>` (on-chain tokens). All endpoints are POST (including queries). Settlement is on-chain (10-60s). KYC required.
- **Strategy**: Strategy API uses `UTA_*` category format ONLY. Do NOT use `linear`/`spot` — map: `linear` → `UTA_USDT`, `spot` → `UTA_SPOT`, `inverse` → `UTA_INVERSE`. Chase orders: `chaseDistance` and `chasePercentE4` are **mutually exclusive** — use ONE only. **NEVER use `category=linear` or `category=spot` in Strategy API calls** — this will cause er
Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.
| Endpoint | Path | Method | Required Params | Optional Params |
|----------|------|--------|----------------|-----------------|
| Send Chat Message | `/v5/p2p/order/message/send` | POST | message, contentType, orderId, msgUuid | — |
| Upload Chat File | `/v5/p2p/oss/upload_file` | POST | upload_file (multipart/form-data) | — |
| Get Chat Messages | `/v5/p2p/order/message/listpage` | POST | orderId | size, lastMsgId |
Code or instructions that leak agent conversation context to external services, potentially exposing sensitive user interactions.
| Endpoint | Path | Method | Required Params | Optional Params |
|----------|------|--------|----------------|-----------------|
| Send Chat Message | `/v5/p2p/order/message/send` | POST | message, contentType, orderId, msgUuid | — |
| Upload Chat File | `/v5/p2p/oss/upload_file` | POST | upload_file (multipart/form-data) | — |
| Get Chat Messages | `/v5/p2p/order/message/listpage` | POST | orderId | size, lastMsgId |
#### Key Notes
The module presents authenticated order-creation and cancellation flows but does not prominently warn that these are irreversible, real-money operations with immediate financial consequences. In trading context, omission of clear warnings and confirmation requirements is dangerous because users may treat examples as informational rather than execution-sensitive, leading to unintended live orders, asset sales, or losses.
The futures bot sections describe leveraged bot creation and management but omit explicit warnings about leverage magnifying losses, liquidation risk, and the possibility of rapid loss of margin. Because this is an execution-oriented trading skill using authenticated writes, users could initiate leveraged strategies from natural language without appreciating that liquidation or forced closure can occur quickly.
The martingale bot section documents a high-risk averaging strategy and optional auto-cycling, yet it lacks explicit warnings that martingale behavior can compound exposure into adverse moves and that auto-restart can continue risk accumulation without fresh user review. In the context of a live trading skill, this omission is especially dangerous because it can normalize a strategy prone to outsized drawdowns and liquidation under volatile conditions.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
### 1. Get an API Key
1. Log in to [Bybit](https://www.bybit.com) → API Management → Create New Key
2. Enable **Read + Trade** permissions only (never enable Withdraw for AI use)
3. Recommended: bind your IP and use a dedicated sub-account with limited balance
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
### Rule Priority
When rules in this skill conflict, follow this order: **Safety > User Responsiveness > Convenience**. For example, never skip confirmation to be faster.
### Version
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
### Step 1: Get an API Key
1. Log in to [Bybit](https://www.bybit.com) → API Management → Create New Key
2. Permissions: enable **Read + Trade only** (NEVER enable Withdraw for AI use)
3. Recommended: bind your IP address (makes the key permanent; otherwise expires in 3 months)
4. **Strongly recommended**: Create a dedicated **sub-account** for AI trading with limited balance
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
For local CLI (Claude Code, Cursor, shell):
# Add to ~/.zshrc or ~/.bashrc, then restart your terminal:
export BYBIT_API_KEY="your_api_key"
export BYBIT_API_SECRET="your_secret_key"
export BYBIT_ENV="testnet"
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.
{ "env": { "vars": { "BYBIT_API_KEY": "...", "BYBIT_API_SECRET": "...", "BYBIT_ENV": "testnet" } } }
**On first use:** Check if `BYBIT_API_KEY` and `BYBIT_API_SECRET` are set. If missing, tell the user which variable is absent and show the setup instructions above. Do NOT proceed until both variables are present. Do NOT ask the user to paste keys in the conversation.
**Display rules** (never show full credentials):
- API Key: show first 5 + last 4 characters (e.g., `AbCdE...x1y2`)
The skill instructs the agent to automatically run connection-verification API calls on first use without a per-action user request. Even though these are framed as safety checks, they still cause autonomous external actions with user credentials and expand the attack surface for unintended data access or prompt-triggered behavior.
After credentials are configured, automatically run these checks:
# 1. Clock sync check (no auth needed)
The skill contains concrete instructions and example code to transmit authenticated trading requests, including API-key-bearing headers and signed order payloads, to an external Bybit endpoint. In a trading skill, that behavior is expected, but it still represents a real security-sensitive capability because compromise, misuse, prompt-injection-driven execution, or accidental use on mainnet can trigger real-money actions with the user's credentials.
PARAM_STR="${TIMESTAMP}${API_KEY}${RECV_WINDOW}${BODY}"
SIGN=$(echo -n "$PARAM_STR" | openssl dgst -sha256 -hmac "$SECRET_KEY" | cut -d' ' -f2)
curl -s -X POST "${BASE_URL}/v5/order/create" \
-H "Content-Type: application/json" \
-H "X-BAPI-API-KEY: ${API_KEY}" \
-H "X-BAPI-TIMESTAMP: ${TIMESTAMP}" \
The module documents a state-changing internal transfer endpoint with a concrete POST example but provides no requirement for an explicit user confirmation, preview of affected accounts/amounts, or warning that this moves real funds between account buckets. In a natural-language trading skill, an agent could interpret ambiguous user requests and trigger unintended transfers, changing margin availability or liquidation risk even if funds do not leave the exchange.
The borrow and repay endpoints can create debt, alter liability composition, and consume user assets, yet the module presents them as straightforward actions without prominent financial-risk warnings or mandatory confirmation guidance. In the context of an AI-driven trading skill handling authenticated real-money accounts, this is especially dangerous because misinterpretation or prompt injection could cause unwanted leverage, repayment of the wrong liability type, or forced account state changes with direct financial consequences.
These endpoints document authenticated repay, adjust-LTV, cancel, renew, and similar loan actions that can directly change a user's financial position, but the module provides no explicit warning that they are live account-affecting operations. In an AI skill that accepts natural-language instructions and uses API credentials, omission of strong risk and confirmation guidance increases the chance of accidental irreversible financial actions.
The RFQ block-trading endpoints include create RFQ, create quote, execute quote, and acceptance actions that may bind the user to executable trading commitments, yet the documentation lacks clear warnings about financial finality and account impact. In the context of a trading skill, this omission is especially dangerous because users may treat these as informational requests rather than actions that can commit capital.
The spread trading section includes live order creation, amendment, cancellation, and cancel-all endpoints without clearly warning that they can execute real trades or alter open market exposure. Given this skill's purpose is trading via natural language and it uses authenticated credentials, insufficient warning and confirmation controls can lead to unintended execution or liquidation-related loss.
The scenario trigger examples are broad and action-oriented in a real-money trading skill, including phrases like 'Buy a meme coin' and 'Sell my on-chain tokens' without clear guardrails or exclusion boundaries. In an agent-routing context, this can cause accidental invocation of a high-risk trading workflow from ordinary conversation, increasing the chance of unintended financial actions or exposure of sensitive asset data.
The module provides concrete authenticated follow-binding instructions that commit real funds, but it does not require an explicit per-action confirmation immediately before executing the bind. Because this skill is for real-money trading and accepts natural-language requests, an agent could translate an ambiguous or impulsive user message directly into a copy-trading enrollment with a specified investment amount, causing unauthorized or unintended financial exposure.
The position-closing instructions describe a destructive authenticated market action that can liquidate or materially alter a user's exposure, yet they do not require an explicit confirmation step. In a trading context, allowing an agent to close positions from conversational input without a clear confirm-before-execute control creates a substantial risk of accidental loss realization, strategy disruption, or abuse from prompt manipulation.