Back to skill

Security audit

Polymarket 48h Player Prop Consistency Trader

Security checks for vulnerabilities and agentic risk

Overview

This trading skill is not clearly malicious, but it needs review because some stated financial safeguards are not fully enforced and it uses an unpinned trading SDK with a trading API key.

Review before installing. Use only a dedicated, least-privilege Simmer/Polymarket key, keep live mode off unless you accept real financial risk, independently cap account exposure outside this skill, and prefer a pinned reviewed version of simmer-sdk. Do not rely on the documented minimum-volume or maximum-open-position safeguards until the implementation is 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)

T08 · Insecure Dependencies

Warning
Location
clawhub.json:6
Finding

Unpinned Third-Party Trading SDK Creates a Supply-Chain Risk

Content
View full analysis
Remediation
View remediation
" ] ``` 2. Use a lockfile or requirements file containing cryptographic hashes, and install with hash verification. 3. Prefer prebuilt artifacts from a controlled package repository or mirror. 4. Review the pinned package and its transitive dependencies before deployment. 5. Run the trader in a restricted container with: - A read-only filesystem where practical. - Minimal environment variables. - Outbound network access limited to required trading endpoints. - A dedicated, least-privilege API credential. 6. Establish dependency monitoring and require explicit review before upgrading the SDK. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:300
Finding

Configured Minimum Market Volume Safeguard Is Never Enforced

Content
View full analysis
tuple[bool, str]: 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" ``` ### Technical Analysis `SIMMER_MIN_VOLUME` is exposed as a tunable and documented as a minimum market-volume filter. Although its value is parsed and refreshed by `get_client()`, neither `valid_market()` nor `find_markets()` compares a market's volume against `MIN_VOLUME`. As a result, setting this control has no effect. Any matching market with a usable probability can pass validation regardless of liquidity, provided it does not fail the implemented spread or resolution-time checks. Low-volume markets are more susceptible to price manipulation and may have insufficient depth for the intended order size. A displayed spread alone does not necessarily establish that adequate ...[truncated 1207 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:420
Finding

Maximum Open-Position Limit Only Caps Successful Orders Within One Run

Content
View full analysis
= MAX_POSITIONS: break market = opp[0] side, size, reasoning = compute_signal(market, opp) if not side: print(f" [skip] {reasoning}") continue ok, why = context_ok(client, market_id) if not ok: 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}" print(f" [trade] {side.upper()} ${size} {tag} {status} -- {reasoning[:110]}") if r.success: placed += 1 except Exception as e: print(f" [error] {market_id}: {e}") ``` ### Technical Analysis `MAX_POSITIONS` is described as the maximum number of concurrent open positions. The implementation instead initializes `placed` to zero on every invocation and only counts successful trade requests made during that invocation. It does not query: - Existing open positions. - Pending or unfilled orders. - Positions opened by an earlier run. - Relevant positions opened through another process using the same account. Therefore, the control is a per-run order count rather than an account-level concurrent-position limit. Repeated invocations can accumulate substantially more open positions than the ...[truncated 1343 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 (6)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill declares access to a high-value credential (SIMMER_API_KEY) and describes trading behavior, but the manifest shown does not define an explicit tool/permission scope. In agent environments, missing scope declarations can lead to broader-than-necessary environment access, increasing the chance that secrets are exposed to unrelated logic or mishandled by downstream code.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest requires an API credential and clearly describes automated trading behavior, but it provides no user-facing disclosure about what the credential will be used for or that the skill may place external trades. In a trading skill, this omission is materially risky because users may supply sensitive credentials without understanding account access, financial exposure, or external side effects.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring explicitly claims the skill 'also detects within-team hierarchy inconsistencies' where star players should be priced higher than role players on the same team. However, the executable logic only groups markets by player and analyzes cross-stat consistency for that same player; parsed team data is stored but never used for hierarchy comparisons.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The inline documentation states that the skill detects star-vs-role-player hierarchy inconsistencies within a team. In practice, no function compares one player's lines against teammates, and the only analysis performed is per-player cross-stat agreement/divergence.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest description scopes the skill to detecting cross-stat consistency or divergence for NBA player props. Line L016 broadens the claimed behavior to a general template that handles market discovery, trade execution, and safeguards independently of the specific strategy, which is a wider operational role than the manifest describes.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
73% confidence
Finding

The file asserts that execution defaults to paper trading and requires --live for real trades, but no enforceable implementation is present here. In a trading skill, unsupported safety claims can cause operators to assume funds are protected when the actual runtime may permit live execution or fail-open behavior, leading to unintended financial loss.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.