T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/scanner.py:92
- Finding
- Advertised Trading Safety Controls Are Not Enforced<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scanner.py:92-164`; conflicting security claims in `SKILL.md:32-39` and `SKILL.md:61-69` **Vulnerability Type**: Missing financial risk controls and unsafe automated trading behavior **Risk Level**: High The documentation states that the Skill enforces daily trading limits, stop-loss thresholds, and human confirmation for real USDC trades: ```markdown | Rule | Virtual ($SIM) | Real (USDC) | |------|---------------|-------------| | Single trade | ≤10% balance | ≤$100 | | Daily limit | ≤30% balance | ≤$500 | | Stop-loss | -15% | -10% | | Max positions | 5 | 3 | | Min opportunity score | 25 | 40 | | Min divergence | 3% | 5% | ``` ```markdown ## Risk Controls - All trades logged to `trading_log.jsonl` - Serious spread warnings (>10%) auto-skip - Already-held markets auto-skip - Balance <$100 auto-stop - Real USDC trades require human confirmation ``` However, the automated scan directly submits trades without implementing those controls: ```python def cmd_scan(): log("=== Market scan started ===") # 1. Status status = api_get("agents/me") balance = status.get("balance", 0) log(f"Balance: ${balance:.2f} SIM") if balance < CONFIG["min_balance"]: log(f"Balance below ${CONFIG['min_balance']}, stopping") return # 2. Positions positions = api_get("positions") active = [p for p in positions.get("positions", []) if p.get("shares", 0) > 0.01] log(f"Active positions: {len(active)}") if len(active) >= CONFIG["max_positions"]: log(f"Max positions ({CONFIG['max_positions']}) reached, skipping") return # 3. Scan opps = api_get("markets/opportunities?limit=20") opportunities = opps.get("opportunities", []) log(f"Found {len(opportunities)} opportunities") trades = 0 held_ids = {p.get("market_id") for p in active} for opp in opportunities: score = opp.get("opportunity_score", 0) divergence ...[truncated 4767 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Enforce daily limits persistently** - Store successful trade identifiers, timestamps, currency or settlement mode, and notional amounts in a durable ledger. - Before every trade, calculate the current UTC day's cumulative notional. - Reject a transaction if the proposed amount would exceed either the percentage-based or absolute daily limit. - Use server-reported transaction history as the authoritative source where available, rather than relying solely on a mutable local log. 2. **Separate virtual and real trading policies** - Determine the account and settlement mode before scanning. - Apply distinct score, divergence, position-count, per-trade, and daily limits for SIM and USDC. - Fail closed if the mode cannot be determined reliably. 3. **Require explicit confirmation for real trades** - When real trading is enabled, display the market, side, amount, current price, maximum loss, and applicable limits. - Require an explicit interactive confirmation immediately before each trade. - Disable real trading in cron and other non-interactive environments unless a separately designed, explicit opt-in policy is present. - Do not treat a generic environment variable or the presence of an API key as human confirmation. 4. **Implement stop-loss management** - Retrieve current position cost and value, calculate unrealized loss consistently, and compare it with the correct mode-specific threshold. - Submit an exit only after validating liquidity, spread, and expected execution. - Document whether stop-loss behavior is guaranteed, best-effort, or dependent on recurring scanner execution. 5. **Prevent race conditions** - Protect the daily ledger with file locking or transactional storage. - Revalidate balance, open positions, and daily exposure immediately before submission. - Where supported, provide an idempotency key to prevent duplicate trades after retries. 6. **Add automated ...[truncated 475 chars]
