Back to skill

Security audit

Polymarket Whale Streak Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed trading skill, but its live-trading path has safety gaps that could place real-money trades in unintended markets or exceed the documented position limit.

Review carefully before installing, especially if you intend to use --live. Use a dedicated low-limit Simmer/Polymarket API key, keep the skill in paper mode until market matching and portfolio-limit enforcement are improved, and pin or otherwise verify simmer-sdk before giving it credentials.

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

Error
Location
clawhub.json:3
Finding

Unpinned Trading SDK Creates a Supply-Chain and Credential Exposure Risk

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:480
Finding

Ambiguous Substring Matching Can Execute Trades on the Wrong Market

Content
View full analysis
3] if not title_words: continue for q_lower, mlist in market_lookup.items(): matches = sum(1 for w in title_words if w in q_lower) if matches >= max(2, len(title_words) // 2): matched_market = mlist[0] break if not matched_market: safe_print(f" [no-match] {title[:60]} -- no Simmer market found") continue ``` The selected object is subsequently used as the trade target: ```python r = client.trade( market_id=matched_market.id, side=side, amount=size, source=TRADE_SOURCE, skill_slug=SKILL_SLUG, reasoning=whale_reasoning, ) ``` ### Technical Analysis A public Polymarket activity title is associated with a Simmer market using only partial word overlap. Words are checked as substrings rather than as normalized tokens, and a candidate is accepted when at least two words or approximately half of the source words appear in its question. The algorithm does not validate a canonical condition ID, token ID, event ID, resolution criteria, outcome mapping, or uniqueness of the result. When multiple candidates qualify, it selects `mlist[0]` from the first qualifying lookup entry and stops searching. The selected market can therefore be semantically different from the whale's actual position. This flaw directly affects a security-sensitive sink: the selected object's identifier is passed to `client.trade`. Spread, volume, date, and slippage checks do not establish that the selected market represents the intended event. ### Attack Path 1. A HOT wallet has an activity title containing words shared by several prediction markets. 2. Market discovery returns an unrel ...[truncated 1478 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:466
Finding

Documented Concurrent-Position Limit Is Not Enforced Across Runs

Content
View full analysis
= MAX_POSITIONS: break ``` Only orders successfully submitted during the current invocation increment that counter: ```python try: r = client.trade( market_id=matched_market.id, side=side, amount=size, source=TRADE_SOURCE, skill_slug=SKILL_SLUG, reasoning=whale_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} -- {whale_reasoning[:120]}") if r.success: placed += 1 ``` The documentation describes a stronger guarantee: ```markdown | Max positions | 8 | Hard cap on concurrent positions | ``` ### Technical Analysis `MAX_POSITIONS` is implemented as a per-process successful-order limit, not as a cap on concurrent open positions. The code never queries the trading account for existing positions before calculating remaining capacity. The local `placed` variable is reset to zero whenever the script starts. Consequently, previous open positions do not consume capacity, and a later execution may place another full batch of orders. The code also does not clearly prevent repeated orders in a market where the account already has exposure. This behavior contradicts the documented “hard cap on concurrent positions” and can cause operators to rely on a safeguard that is not ...[truncated 1490 chars]
Remediation
View remediation
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 (3)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill description frames the behavior as tracking and following hot wallets, but the file documents materially broader capabilities: market discovery, independent signal generation, external API usage, and actual trade execution when run live. This mismatch is dangerous because operators may approve or invoke the skill under a narrower trust model than its real behavior, leading to unexpected financial actions and external data flows.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares no explicit tool scope or permissions even though its documented behavior requires environment access and network/API interaction. That creates an authorization and transparency gap: a user or platform may treat the skill as low-risk documentation while it can actually access secrets and external services, increasing the chance of unintended data exposure or unreviewed outbound actions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This JSON manifest is in scope for missing-warning review because it is a markdown/manifest-style skill descriptor, and it explicitly requires the sensitive environment variable SIMMER_API_KEY. The file provides no accompanying disclosure that the skill uses credentials to access an external service or may place trades on the user's behalf, which is material to user privacy and system/account integrity.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.