T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/auto_copytrade.py:116
- Finding
- Unbounded Repeated Financial Order Execution<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auto_copytrade.py:116-166, 178-185` **Vulnerability Type**: Missing cumulative exposure controls, order deduplication, and configuration validation **Risk Level**: High ### Relevant Code ```python def process_once(cfg, execute=False): print(f"\n[{datetime.now().isoformat(timespec='seconds')}] scan start") sig = cfg.get("signatureType", "eoa") max_concurrent = int(cfg.get("maxConcurrent", 2)) placed = 0 for r in cfg.get("rules", []): if placed >= max_concurrent: print("- hit maxConcurrent, stop this cycle") break ``` ```python idx = find_outcome_index(market["outcomes"], r["outcome"]) price = market["prices"][idx] token_id = market["token_ids"][idx] max_entry = float(r["maxEntryPrice"]) amount = float(r["amount"]) print(f" market={r['marketSlug']} outcome={r['outcome']} price={price:.3f} threshold<={max_entry:.3f}") if price > max_entry: print(" skip: price above threshold") continue res = place_order(token_id, amount, sig, execute) placed += 1 print(" order:", json.dumps(res, ensure_ascii=False)) ``` ```python while True: try: process_once(cfg, execute=args.execute) except Exception as e: print("scan error:", e) time.sleep(args.interval) ``` ### Technical Analysis The `maxConcurrent` setting does not limit concurrent open positions. It only limits the number of order attempts made during a single invocation of `process_once()`. The local `placed` counter is reset to zero at the beginning of every monitoring cycle. When the script is run with both `--execute` and a positive `--interval`, each qualifying rule can therefore submit another authenticated market order during every cycle. The implementation does not: - Query existing positions or outstanding orders. - Check whether the sam ...[truncated 2541 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Enforce actual position limits** - Query open positions and outstanding orders before submitting any order. - Calculate current exposure by market, outcome, and account. - Treat failure to retrieve account state as a blocking error in live mode. 2. **Prevent duplicate execution** - Assign a stable identifier to each rule and trading signal. - Persist submitted order IDs, market IDs, timestamps, and signal state. - Do not submit another order for the same signal unless an explicit re-entry policy permits it. - Use idempotency support from the trading API where available. 3. **Implement hard financial limits** - Enforce a non-configurable or separately trusted maximum order amount. - Add maximum daily spend, maximum per-market exposure, maximum total exposure, and maximum outstanding-order limits. - Compare limits against actual account state rather than an in-memory per-cycle counter. 4. **Validate configuration strictly** - Require `amount` and `maxEntryPrice` to be finite numeric values. - Require `amount > 0`. - Constrain `maxEntryPrice` to the valid market price range. - Require `maxConcurrent` to be a positive integer within a conservative upper bound. - Reject unknown signature types and malformed rules before entering the monitoring loop. 5. **Implement documented loss controls** - Track settled outcomes and consecutive losses. - Stop live trading after the configured daily loss limit or consecutive-loss threshold. - Persist this state so restarting the process cannot bypass the limit. 6. **Strengthen live-mode confirmation** - Display the account, maximum order size, daily budget, and total exposure limit before live execution. - Require explicit confirmation or a dedicated production configuration flag. - Consider requiring a separate confirmation for configurations exceeding conservative defaults. 7. **Improve naming and documentation** - Renam ...[truncated 222 chars]
