Back to skill

Security audit

Polymarket Candle Timeframe Mismatch Trader

Security checks for vulnerabilities and agentic risk

Overview

This skill is disclosed as a trading bot, but its live-trading risk controls do not fully match the safeguards it documents.

Review carefully before installing or enabling live mode. Use only a restricted API key, keep live balances and venue-side limits low, do not rely on the documented volume and position controls as complete, and avoid live use until the dependency is pinned and the risk-control bugs are 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 (4)

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

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:363
Finding

Declared Minimum-Volume Safeguard Is Not Enforced Before Trading

Content
View full analysis
= MAX_POSITIONS: break coin, date_str, hour_start = key sub_intervals = fivemin_by_hour.get(key, []) if len(sub_intervals) < MIN_CONSENSUS: safe_print( f" [{coin} {date_str} {hour_start//60}h] " f"only {len(sub_intervals)} sub-intervals, need {MIN_CONSENSUS}" ) continue sorted_subs = sorted(sub_intervals, key=lambda x: x[0]) up_count = 0 down_count = 0 for _, sub_m in sorted_subs: p = float(sub_m.current_probability) if p > UP_BIAS_THRESHOLD: up_count += 1 elif p < DOWN_BIAS_THRESHOLD: down_count += 1 consensus_dir = None consensus_count = 0 if up_count >= MIN_CONSENSUS: consensus_dir = "up" consensus_count = up_count elif down_count >= MIN_CONSENSUS: consensus_dir = "down" consensus_count = down_count if not consensus_dir: safe_print( f" [{coin} {date_str} {hour_start//60}h] " f"no consensus (up={up_count}, down={down_count}, need {MIN_CONSENSUS})" ) continue hourly_p = float(hourly_m.current_probability) safe_print( f" [{coin} {date_str} {hour_start//60}h] " f"5min consensus={consensus_dir}({consensus_count} ...[truncated 2262 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:363
Finding

Maximum Concurrent Position Limit Only Counts Orders Placed During the Current Run

Content
View full analysis
= MAX_POSITIONS: break ``` It is incremented only after a successful order during that invocation: ```python try: r = client.trade( market_id=hourly_m.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}" safe_print(f" [trade] {side.upper()} ${size} {tag} {status} -- {reasoning[:100]}") if r.success: placed += 1 ``` ### Technical Analysis `MAX_POSITIONS` is described as the maximum number of concurrent open positions, but the implementation treats it as a maximum number of successful orders placed by one process invocation. The code does not query existing open positions or pending orders before initializing `placed`. It also does not reserve capacity atomically. Repeated or concurrent runs can therefore each observe a local count of zero and place up to `MAX_POSITIONS` additional orders. A successful order count is not equivalent to an open-position count. Existing exposure from earlier invocations remains unaccounted for, and multiple successful orders can also affect the same position. ### Attack Path 1. The account already has open positions created by a previous run. 2. The skill is invoked again in live mode. 3. `placed` is reset to zero without querying account exposure. 4. The new invocation discovers additional qualifying markets. 5. It submits up to `MAX_POSITIONS` additional successful orders. 6. Repeating the invocation, or running multiple instances concurrently, continues increasing exposure beyon ...[truncated 560 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:259
Finding

Minimum Trade Size Can Override the Configured Maximum Position Size

Content
View full analysis
Remediation
View remediation
MAX_POSITION`. 2. Explicitly clamp every calculated amount to `MAX_POSITION`. 3. If the bounded calculated amount is below the venue's minimum order size, skip the trade rather than violating the maximum. 4. Use a sizing sequence such as: ```python if MIN_TRADE > MAX_POSITION: raise ValueError("SIMMER_MIN_TRADE must not exceed SIMMER_MAX_POSITION") calculated = round(conviction * MAX_POSITION, 2) if calculated < MIN_TRADE: calculated = MIN_TRADE size = min(calculated, MAX_POSITION) ``` 5. Enforce the same invariant in `clawhub.json` or the management UI if cross-field validation is supported. 6. Add a final independent amount check immediately before `client.trade()`. 7. Add boundary tests for equal limits, minimum greater than maximum, zero or negative environment overrides, non-finite numbers, and out-of-range direct environment values. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill explicitly requires a high-value credential (SIMMER_API_KEY) and describes trading execution, but it does not declare any explicit tool scope such as permissions or allowed-tools. That mismatch weakens least-privilege controls and can let an agent access environment-backed capabilities without clear, reviewable restriction, which is especially risky in a trading skill that can place orders.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The phrase 'Convergence guarantee' presents a trading thesis as certain, which can mislead operators or downstream agents into treating speculative financial behavior as deterministic. In context, this is dangerous because the skill can be switched to live trading, so overstated certainty can directly drive unjustified risk-taking with real funds.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Saying the outcome is 'not a question of if, but when' implies inevitability of profit or directional resolution, which is an unjustified certainty claim for a live-capable trading strategy. This can bias users or autonomous systems to overtrust the signal, ignore contrary evidence, and accept elevated financial exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest explicitly requires an API credential and describes an automated trading skill, but it provides no user-facing warning that the skill will perform external networked trading activity using that credential. This creates a transparency and consent risk: users may supply sensitive credentials and enable live trading without clearly understanding the external actions, financial exposure, or data flows involved.

Content

No source excerpt is available for this finding.