T09 · Insecure Skill Coding Practices
- Location
trader.py:432- Finding
Configured Concurrent Position Limit Is Not Enforced Across Runs
- Content
View full analysis
= MAX_POSITIONS: break market = opp[0] side, size, reasoning = compute_signal(market, opp) if not side: safe_print(f" [skip] {reasoning}") continue ok, why = context_ok(client, market_id) if not ok: safe_print(f" [skip] {why}") continue try: r = client.trade( market_id=market_id, side=side, amount=size, source=TRADE_SOURCE, skill_slug=SKILL_SLUG, reasoning=reasoning, ) tag = "(sim)" if r.simulated else "(live)" status = "OK" if r.success else f"FAIL:{r.error}" safe_print(f" [trade] {side.upper()} ${size} {tag} {status} -- {reasoning[:110]}") if r.success: placed += 1 ``` ### Technical Analysis The `MAX_POSITIONS` setting is documented as the maximum number of concurrent open positions. The implementation does not query existing account positions or outstanding orders. Instead, it initializes `placed` to zero for every invocation and only increments it when an order succeeds during that invocation. Consequently, the limit is an order-count limit for one process run rather than an account-wide concurrent-position limit. Repeated manual or automated executions can each submit up to `MAX_POSITIONS` additional orders. The check is also not atomic with order placement. If multiple instances execute concurrently, every instance maintains its own counter and can independently consume the full configured allowance. ### Attack Path 1. The skill is configured with `SIMMER_MAX_POSITIONS=8`. 2. A live invocation finds eight qualifying opportunities and successful ...[truncated 852 chars]- Remediation
View remediation
