Back to skill

Security audit

Polymarket Sports Live Trader

Security checks for vulnerabilities and agentic risk

Overview

This trading skill is paper-by-default, but its live mode can place real-money orders while relying on documented risk controls that are mismatched or not enforced.

Review this before installing or enabling live mode. It is not showing hidden exfiltration or automatic startup, but it can trade with real funds and the documented safeguards do not fully match the code. Use paper mode unless the volume filter, default values, final position-size cap, date parsing behavior, open-position accounting, and dependency pinning are corrected and tested.

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:27
Finding

Declared market and portfolio risk controls are missing or weaker at runtime

Content
View full analysis
tuple[str | None, float, str]: p = market.current_probability q = market.question # Spread gate if market.spread_cents is not None and market.spread_cents / 100 > MAX_SPREAD: return None, 0, f"Spread {market.spread_cents/100:.1%} > {MAX_SPREAD:.1%}" # Days-to-resolution gate if market.resolves_at: try: resolves = datetime.fromisoformat(market.resolves_at.replace("Z", "+00:00")) days = (resolves - datetime.now(timezone.utc)).days if days < MIN_DAYS: return None, 0, f"Only {days} days to resolve" except Exception: pass bias = sport_bias(q) if p <= YES_THRESHOLD: conviction = min(1.0, (YES_THRESHOLD - p) / YES_THRESHOLD * bias) size = max(MIN_TRADE, round(conviction * MAX_POSITION, 2)) edge = YES_THRESHOLD - p return "yes", size, f"YES {p:.0%} edge={edge:.0%} bias={bias:.2f}x size=${size} — {q[:65]}" if p >= NO_THRESHOLD: conviction = min(1.0, (p - NO_THRESHOLD) / (1 - NO_THRESHOLD) * bias) size = max(MIN_TRADE, round(convicti ...[truncated 3424 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:214
Finding

Minimum trade setting can override the maximum position limit

Content
View full analysis
= NO_THRESHOLD: conviction = min(1.0, (p - NO_THRESHOLD) / (1 - NO_THRESHOLD) * bias) size = max(MIN_TRADE, round(conviction * MAX_POSITION, 2)) edge = p - NO_THRESHOLD return "no", size, f"NO YES={p:.0%} edge={edge:.0%} bias={bias:.2f}x size=${size} — {q[:65]}" ``` The exposed configuration ranges permit an inconsistent state: ```json { "env": "SIMMER_MAX_POSITION", "default": 25, "range": [ 1, 200 ], "step": 1, "label": "Max position size (USD)" } ``` ```json { "env": "SIMMER_MIN_TRADE", "type": "number", "default": 5, "range": [ 1, 100 ], "step": 1, "label": "Min trade size (USD)" } ``` ### Technical Analysis The order size is calculated with `max(MIN_TRADE, calculated_size)`, but it is never capped again at `MAX_POSITION`. If `MIN_TRADE` is configured above `MAX_POSITION`, the minimum-trade floor becomes the effective order size and directly bypasses the stated maximum. The configuration schema permits `SIMMER_MAX_POSITION=1` and `SIMMER_MIN_TRADE=100`. Under that configuration, any qualifying signal can generate a $100 order despite a nominal $1 maximum. The same issue affects both YES and NO orders. ### Attack Path 1. Through the Simmer UI or environment variables, set `SIMMER_MAX_POSITION` to a value lower than `SIMMER_MIN_TRADE`. 2. Start the trader with `- ...[truncated 849 chars]
Remediation
View remediation
MAX_POSITION: raise ValueError("SIMMER_MIN_TRADE must not exceed SIMMER_MAX_POSITION") ``` 2. Apply an explicit final cap to both branches: ```python calculated = round(conviction * MAX_POSITION, 2) size = min(MAX_POSITION, max(MIN_TRADE, calculated)) ``` 3. Constrain the configuration UI so the minimum trade cannot be set above the current maximum position. 4. Revalidate configuration after `apply_skill_config()` changes environment variables. 5. Add unit tests for equal limits, inverted limits, boundary probabilities, zero conviction, and the maximum values allowed by the schema. 6. Consider aborting rather than silently correcting invalid financial settings so operators cannot unknowingly run with a policy different from the one they configured. ]]>

T08 · Insecure Dependencies

Warning
Location
clawhub.json:3
Finding

Security-sensitive trading dependency is not version-pinned

Content
View full analysis
Remediation
View remediation
" ] ``` 2. Use a lockfile or deployment mechanism that records cryptographic hashes for all direct and transitive packages. 3. Install from the official package index over authenticated TLS and disallow unexpected alternate indexes. 4. Review release notes and source changes before upgrading the pinned version. 5. Run dependency vulnerability and provenance checks in CI. 6. Restrict `SIMMER_API_KEY` to the minimum venue permissions and financial limits required. 7. Isolate the process and avoid exposing unrelated credentials in its environment. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The description promises league table, injury, and Elo-driven trading, but the actual documented behavior is a simple threshold-and-bias heuristic with no corresponding data ingestion. This mismatch can mislead operators into granting trust, capital, or permissions under false assumptions, which is especially dangerous in a live trading skill where strategy quality directly affects financial loss.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documents access to a high-value credential (SIMMER_API_KEY) and describes trade execution, but it does not declare any explicit tool scope or allowed-tools boundary. In an agent environment, missing permission scoping can let the skill access environment secrets more broadly than users expect, increasing the chance of credential misuse or unintended execution paths.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The skill claims it exploits edges 'without any external API' while elsewhere advertising remix paths that depend on external sports feeds and data providers. This inconsistency can cause users to misunderstand the trust boundary, reproducibility, and operational dependencies of the strategy, leading to unsafe deployment decisions or overconfidence in how signals are derived.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

Although the mode table notes paper versus live trading, the skill lacks a strong, prominent warning that enabling --live can execute real-money trades using a privileged API key. In a financial automation context, insufficient warning and friction can increase the risk of accidental live execution, operator misunderstanding, and direct monetary loss.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This manifest declares a required environment variable named SIMMER_API_KEY, which indicates the skill depends on a sensitive credential. In this file there is no accompanying warning or disclosure about credential handling, privacy implications, or the fact that the skill will access authenticated external services.

Content

No source excerpt is available for this finding.