Back to skill

Security audit

Polymarket Bundle Cs2 Maps Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed trading bot, but some live-trading safeguards do not match what the documentation promises.

Review this before installing for live use. Paper mode is the default, but do not run with --live unless the API key is narrowly scoped, the SDK dependency is pinned or otherwise trusted, and you accept that the documented volume and concurrent-position safeguards are not fully enforced by this code.

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)

T08 · Insecure Dependencies

Warning
Location
clawhub.json:6
Finding

Unpinned High-Privilege Trading SDK Dependency

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:372
Finding

Declared Minimum-Volume Trading Safeguard Is Not Enforced

Content
View full analysis
list: """ Find active CS2 markets via keyword search and bulk fetch, deduplicated. Uses get_markets(limit=200) as primary since CS2 markets often appear in bulk. """ seen: set[str] = set() unique: list = [] # Bulk fetch first -- CS2 markets often in bulk try: for m in client.get_markets(limit=200): market_id = getattr(m, "id", None) if market_id and market_id not in seen: q = getattr(m, "question", "") if is_cs2_market(q): seen.add(market_id) unique.append(m) except Exception as e: safe_print(f"[bulk-fetch] {e}") # Keyword search for additional coverage for kw in KEYWORDS: try: for m in client.find_markets(query=kw): market_id = getattr(m, "id", None) if market_id and market_id not in seen: q = getattr(m, "question", "") if is_cs2_market(q): seen.add(market_id) unique.append(m) except Exception as e: safe_print(f"[search] {kw!r}: {e}") return unique ``` The configured safeguard is loaded earlier in the file: ```python MIN_VOLUME = float(os.environ.get("SIMMER_MIN_VOLUME", "5000")) ``` However, neither `find_markets()` nor the later execution path compares a market's volume against `MIN_VOLUME`. ### Technical Analysis `SKILL.md` and `clawhub.json` present `SIMMER_MIN_VOLUME` as a minimum market-volume filter, with a default value of USD 5,000. The implementation reads this setting but never uses it to reject candidate markets. As a result, low-volume or effectively illiquid markets can enter a bu ...[truncated 1434 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:440
Finding

Maximum Concurrent Position Limit Resets on Every Invocation

Content
View full analysis
= MAX_POSITIONS: break ``` The counter is incremented only for successful orders placed during the current process: ```python if r.success: placed += 1 ``` ### Technical Analysis The documentation describes `SIMMER_MAX_POSITIONS` as the maximum number of concurrent open positions. The implementation instead initializes `placed` to zero on every invocation and counts only successful orders submitted during that invocation. It does not query existing open positions, account for positions created by previous runs, detect duplicate exposure to the same market, or reserve capacity against concurrent Skill processes. Thus, the code implements a per-run order limit rather than a concurrent-position limit. Repeated or overlapping executions can each place up to `MAX_POSITIONS` additional orders. This undermines the primary cumulative exposure control and is especially consequential because the Skill supports real-money trading with `--live`. ### Attack Path 1. The Skill is invoked in live mode while existing positions remain open. 2. `placed` is initialized to zero without querying the trading account. 3. The strategy finds qualifying price discrepancies and places up to `MAX_POSITIONS` new orders. 4. The process exits while those positions remain open. 5. The Skill is invoked again manually, through an external scheduler, or by overlapping automation. 6. The counter resets to zero and another set of orders is allowed. 7. Repetition causes the number of open positions and total financial exposure to exceed the configured limit. A race condition also exists if multiple instances start simultaneously: each instance independently sees a local count ...[truncated 576 chars]
Remediation
View remediation
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • 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 (3)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill requires a high-value credential (SIMMER_API_KEY) and implicitly relies on environment access, but it does not declare any explicit tool scope such as permissions or allowed-tools. That creates an overbroad trust boundary: an agent platform may grant broader environment or tool access than is actually needed, increasing the chance of credential exposure or unintended actions if the skill is modified, composed with other skills, or run in a permissive runtime.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest defines a managed trading automaton with an entrypoint but no cron schedule, trigger policy, or other activation constraints. In a trading skill, this ambiguity can allow unintended execution contexts or operator misunderstanding about when the bot may start, increasing the risk of unsupervised or premature trades.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
70% confidence
Finding

Multiple tunable labels hard-code amounts in USD, which may impose a specific currency/locale assumption without any indication of user opt-in or region-specific justification. This can be a natural-language policy concern when a skill presents locale-specific behavior as the default for all users.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.