Back to skill

Security audit

Polymarket Ladder Nhl Hockey Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed trading bot, but its implementation can violate expected paper-trading and risk-limit safeguards, creating real-money exposure users should review carefully.

Review this before installing or running live. Use a restricted SIMMER_API_KEY with minimal funds and permissions, do not rely on paper mode in a persistent worker after any live run, and treat the documented volume and max-position controls as incomplete until fixed.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:75
Finding

Cached Live Trading Client Can Be Reused During a Paper-Mode Run

Content
View full analysis
SimmerClient: global _client, MAX_POSITION, MIN_VOLUME, MAX_SPREAD, MIN_DAYS, MAX_POSITIONS global YES_THRESHOLD, NO_THRESHOLD, MIN_TRADE, MIN_VIOLATION if _client is None: venue = "polymarket" if live else "sim" _client = SimmerClient( api_key=os.environ["SIMMER_API_KEY"], venue=venue, ) if live: _client.live = True ``` ### Technical Analysis The module stores the `SimmerClient` in the global `_client` variable and only configures its venue when `_client` is `None`. It does not verify that an existing client's venue matches the `live` argument passed during subsequent calls. Consequently, if `get_client(live=True)` or `run(live=True)` is called first, `_client` remains configured for the real Polymarket venue. A later call to `run(live=False)` in the same Python process reuses that live client rather than constructing a simulation client. This violates the documented safety guarantee that a run without `--live` is paper-only. The issue is particularly relevant in persistent workers, test harnesses, notebooks, plugin hosts, or managed automation runtimes that import the module and invoke `run()` more than once. ### Attack Path 1. A process imports `trader.py` and has a valid `SIMMER_API_KEY`. 2. An initial invocation calls `run(live=True)`. 3. `get_client()` creates a Polymarket client, sets `_client.live = True`, and stores it globally. 4. The same process later calls `run(live=False)`, expecting simulation. 5. Because `_client` is already initialized, `get_client()` returns the cached live client without checking the requested mode. 6. The execution path reaches `client.trade(...)` using the live Polymarket client. ...[truncated 587 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:477
Finding

Declared Volume and Concurrent-Position Safeguards Are Not Enforced

Content
View full analysis
tuple[bool, str]: """Check basic market quality gates.""" p = getattr(market, "current_probability", None) if not isinstance(p, (int, float)): return False, "missing probability" spread_cents = getattr(market, "spread_cents", None) if isinstance(spread_cents, (int, float)) and spread_cents / 100 > MAX_SPREAD: return False, f"Spread {spread_cents/100:.1%} > {MAX_SPREAD:.1%}" resolves_at = getattr(market, "resolves_at", None) if resolves_at: try: resolves = datetime.fromisoformat(resolves_at.replace("Z", "+00:00")) days = (resolves - datetime.now(timezone.utc)).days if days < MIN_DAYS: return False, f"Only {days} days to resolve" except Exception: pass return True, "ok" ``` The position limit is implemented only as a counter for successful orders in the current invocation: ```python # Execute trades on the largest violations first placed = 0 for market_id, opp in sorted(all_opps.items(), key=lambda x: -x[1][2]): if placed >= 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_sl ...[truncated 2881 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
clawhub.json:7
Finding

Trading SDK Dependency Is Installed Without a Version or Integrity Pin

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill explicitly requires a high-value environment credential (SIMMER_API_KEY) but does not declare any permissions or allowed-tools scope to constrain access. In an agent ecosystem, undeclared environment access weakens least-privilege guarantees and can let the skill read sensitive variables beyond what operators expect, especially given this skill can place trades when run live.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest enables an automated trading skill via a managed automaton entrypoint, but it contains no user-facing disclosure that the skill can place autonomous financial trades or incur losses. In a trading context, this omission is materially risky because users may enable or deploy the skill without understanding that it can execute market actions automatically using configured capital limits.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.