T09 · Insecure Skill Coding Practices
- Location
scripts/order_sign.py:35- Finding
Unvalidated Signing of API-Controlled Hashes and Transactions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill has useful Bitget Wallet features, but it under-discloses live transaction execution, raw private-key signing, and mutable self-update behavior that users should review carefully.
Install only if you intentionally want an agent-assisted wallet trading skill, not just a market-data tool. Do not give it a wallet private key unless you fully trust the environment, understand that signed orders can move funds, and can review every order, approval, gasless/EIP-7702 delegation, dependency, and update before use.
scripts/order_sign.py:35Unvalidated Signing of API-Controlled Hashes and Transactions
scripts/order_sign.py:108Wallet Private Key Exposed Through Command-Line Arguments
scripts/order_sign.py:18Signing Dependency Is Undeclared and Unpinned
SKILL.md:27Mutable Main-Branch Self-Update Loads Remote Skill Code Before Review
The skill instructs retrieval of wallet secrets from 1Password via subprocess for signing. Pulling sensitive secrets into an agent workflow that is advertised as a data/quote integration creates a direct path to key misuse, secret leakage, or unauthorized fund movement.
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
headers["Partner-Code"] = os.environ.get("BGW_PARTNER_CODE", DEFAULT_PARTNER_CODE)
try:
resp = requests.post(url, data=body_str if body_str else None, headers=headers, timeout=30)
if resp.status_code != 200:
return {"error": f"HTTP {resp.status_code}", "message": resp.text[:500]}
return resp.json()
The skill is described as an API helper for data and quotes, but it also documents use of private keys for cryptographic signing and order execution. Undisclosed key handling in a wallet-related skill is especially dangerous because it expands from informational use into direct control over funds.
The skill is described as an API helper for data and quotes, but it also documents use of private keys for cryptographic signing and order execution. Undisclosed key handling in a wallet-related skill is especially dangerous because it expands from informational use into direct control over funds.
This section directs full order creation, presentation, signing, submission, and status polling even though the skill metadata emphasizes data, quotes, and audits. The mismatch increases the risk of an agent performing trades under a misleadingly low-risk label.
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
8. Token safety status
9. EIP-712 verification (domain, msgSender, calls summary)
**Gas mode display rules:**
- Gasless with 7702 bound → "Gasless ✅ (EIP-7702 已绑定)"
- Gasless first time → "Gasless ✅ (EIP-7702 首次绑定, 2 signatures)"
- User override → "User Gas (native token)"
The manifest frames the skill as a Bitget Wallet API data/quote tool, but this section instructs agent-side wallet signing with private keys. That is a substantial hidden expansion of authority from information retrieval to irreversible financial execution.
The documentation recommends spawning local scripts to fetch secrets, which expands the trust boundary and bypasses safer secret-management patterns. Subprocess-based secret access makes auditing harder and increases the risk of exposure through logs, command history, or modified helper scripts.
The file claims swap calldata is for information only and that actual signing requires wallet interaction, yet elsewhere it provides agent-side private-key signing instructions. This contradiction can mislead reviewers and users about the real execution risk and may cause unsafe trust decisions.
The skill metadata frames this tool as a market-data, quote, and security-check client, but the implementation also supports creating swap orders, submitting signed transactions, and broadcasting raw transactions. In an agent setting, that expands the capability from passive information retrieval into active fund movement, which is materially more dangerous because it can facilitate unintended or unauthorized on-chain actions.
Submitting signed transactions and broadcasting them to a third-party API is not justified by the stated purpose of a market-data/quote skill. In practice, these endpoints can turn a seemingly informational integration into an execution pathway for blockchain transactions, increasing the risk of users or downstream agents treating the skill as safe when it can actually move assets.
This helper signs API-provided hashes directly with unsafe_sign_hash and does not independently verify or reconstruct what the user is authorizing. That means a compromised, malicious, or spoofed API response could cause the user to sign arbitrary messages or approvals with their private key. In context, this is more dangerous because the declared skill is primarily read-oriented market/security data, yet the code introduces privileged signing behavior that can authorize fund movement or off-platform abuse.
The script accepts a raw private key and performs signing operations over transactions and message hashes, which materially exceeds the stated skill purpose of providing wallet API data, quotes, and security information. Any misuse of this code path can expose the user's most sensitive credential and enable unauthorized token approvals, transfers, or replayable signed payloads. Because the skill context does not justify custody-like behavior, this capability is especially suspicious and risky.
The compatibility rule is overly broad and encourages any agent with file access, Python execution, and internet access to treat the skill as runnable without additional trust checks, sandboxing, or user consent. In agent ecosystems, this kind of blanket applicability can increase the chance of automatic installation and execution in environments where repo contents, dependencies, or follow-on instructions have not been reviewed.
These instructions normalize autonomous cloning, package installation, and script execution with network access, but do not warn about system modification, dependency risk, or outbound requests. For agentic systems that may follow documentation literally, this can prompt unsafe actions on behalf of the user without an explicit authorization boundary or environment safety guidance.
The skill declares no explicit tool scope despite instructing use of network access and environment variables. In a high-risk domain involving wallets and transaction flows, missing scope boundaries increases the chance the agent can access secrets or make outbound requests beyond what users expect.
The instruction to run multiple risk checks silently before presenting a summary increases autonomous agent behavior in a financial context. While these background reads are not inherently malicious, bundling decisions and reducing step-by-step visibility can make it easier for users to miss what data was gathered and how conclusions were formed.
### Pre-Trade Workflow
Before executing any swap, the agent should silently run risk checks and then present a **single confirmation summary** to the user. Do not prompt the user at every step.
**Behind the scenes (agent runs automatically):**
The status guidance explicitly instructs the agent to show the message "等待确认...", which imposes a specific language on user-facing output. The document does not provide a language choice or frame this as a region-specific requirement, so it conflicts with the locale-choice policy.
The instruction says the user must explicitly say "yes" / "confirm" / "执行", again embedding a specific language as expected interaction. Without opt-in or localization guidance, this is a natural-language policy issue because it biases the interaction toward one locale.
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.
**Why this order matters:**
- order-create before present: user sees real order data, not just estimates
- order-status for toAmount: more accurate than quote (accounts for actual routing)
- present before sign: user controls their funds, agent doesn't auto-execute
- **Skipping the confirmation step is a violation of the agent's operating rules**
**Completion message (same-chain):**
The guidance requires showing an "已提交" message, which is another user-facing locale-specific instruction. The skill lacks any note that outputs should be adapted to the user's language, so this is a policy violation.
The skill mandates always attempting gasless mode and specifically says not to ask the user to choose. In a wallet execution flow, selecting gas/payment mode changes fee source, signing semantics, and trust assumptions, so making that choice autonomously can violate user expectations.
#### Gas Mode: Default to Gasless
**Always default to gasless** — pass `--feature no_gas` to `order-create` on every trade. Do not check `features` field first, do not ask the user to choose.
**How to detect gasless success vs fallback:**
- Response has `signatures` array (non-empty) → gasless mode active ✅
The confirmation summaries embed Chinese text such as "gas 从输入金额扣除" and "已绑定" as required user-visible phrasing. Because the skill does not offer localization or user opt-in, these examples effectively direct the agent to force a specific language.
The skill directs the agent to determine and act on token approval requirements, including sending an approve transaction when needed. Even if framed as necessary workflow, approval grants spending authority to a router and is a sensitive wallet action that should not be treated as automatic background logic.
### EVM Token Approval (Critical)
On EVM chains (Ethereum, BNB Chain, Base, Arbitrum, Optimism), tokens require an **approve** transaction before the router contract can spend them. **Without approval, the swap transaction will fail on-chain and still consume gas fees.**
- Before calling `swap-calldata`, check if the token has sufficient allowance for the BGW router (`0xBc1D9760bd6ca468CA9fB5Ff2CFbEAC35d86c973`).
- If allowance is 0 or less than the swap amount, an approve transaction must be sent first.
The order-submit command sends signed transaction payloads to the Bitget API, but the only notice is in internal docstrings and CLI help text. In an agent-mediated environment, users may not see those warnings, so sensitive signed transaction material can be relayed off-host without an execution-time acknowledgment that this is an irreversible, high-risk action.
No suspicious patterns detected.