Back to skill

Security audit

Polymarket Candle Harami Trader

Security checks for vulnerabilities and agentic risk

Overview

This trading skill is open about needing a trading API key, but its live-trading safety limits are incomplete and can fail open, so it needs review before use with real funds.

Review carefully before enabling live mode. Use paper trading first, provide only a least-privilege trading key, set external account-level limits where available, and do not run this with real funds until the fail-open checks, missing volume enforcement, open-position accounting, and dependency pinning 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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:280
Finding

Market Context Safety Checks Fail Open

Content
View full analysis
tuple[bool, str]: """Check flip-flop and slippage safeguards.""" try: ctx = client.get_market_context(market_id) if not ctx: return True, "no context" if ctx.get("discipline", {}).get("is_flip_flop"): reason = ctx["discipline"].get("flip_flop_reason", "recent reversal") return False, f"Flip-flop: {reason}" slip = ctx.get("slippage", {}) if isinstance(slip, dict) and slip.get("slippage_pct", 0) > 0.15: return False, f"Slippage {slip['slippage_pct']:.1%}" for w in ctx.get("warnings", []): safe_print(f" [warn] {w}") except Exception as e: safe_print(f" [ctx] {market_id}: {e}") return True, "ok" ``` ### Technical Analysis The function is responsible for rejecting trades when market context indicates excessive slippage or recent flip-flop behavior. However, it approves the trade when no context is returned and also catches every exception before returning `True`. Consequently, timeouts, authentication errors, malformed API responses, SDK failures, and unexpected context schemas all bypass the intended safeguards. This is a fail-open design in a control directly preceding financial order submission. ### Attack Path 1. The program detects a candidate market and produces a trade signal. 2. The program calls `client.get_market_context(market_id)`. 3. The context service returns no data or raises an exception due to an outage, malformed response, or other failure. 4. The function returns `True`, despite not having verified slippage or flip-flop status. 5. In live mode, execution proceeds to `client.trade()`. 6. A real order can therefore be submitted without the advertised cont ...[truncated 514 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:224
Finding

Resolution-Time Safeguard Fails Open on Invalid Timestamps

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:24
Finding

Declared Minimum-Volume Safeguard Is Not Enforced

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:318
Finding

Maximum Concurrent Position Limit Only Counts Orders in the Current Run

Content
View full analysis
= MAX_POSITIONS: break side, size, reasoning = compute_signal(m, harami_dir, p_large, p_small) if not side: safe_print(f" [skip] {reasoning}") continue ok, why = context_ok(client, m.id) if not ok: safe_print(f" [skip] {why}") continue try: r = client.trade( market_id=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[:70]}") if r.success: placed += 1 ``` ### Technical Analysis The metadata and documentation describe `SIMMER_MAX_POSITIONS` as a maximum number of concurrent open positions. The implementation instead initializes a local counter to zero on every invocation and increments it only after successful orders during that invocation. It does not query existing open positions, pending orders, or orders submitted by concurrent process instances. Therefore, repeated, overlapping, or scheduled executions can each place up to the configured number of additional orders. This is also a time-of-check/time-of-use concern: even if an initial position count were added, concurrent workers would still require atomic reservation or server-side enforcement. ### Attack Path 1. The account already has open positions, or the script completes a run that creates positions. 2. The script is invoked again while those positions remain open. 3. `placed` is reset to zero. 4. The n ...[truncated 633 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
clawhub.json:6
Finding

Security-Critical Trading SDK Dependency Is Unpinned

Content
View full analysis
Remediation
View remediation
\ --hash=sha256: ``` ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill declares access to a high-value environment credential (SIMMER_API_KEY) but does not define any explicit tool scope such as permissions or allowed-tools. In an agent setting, missing scope boundaries can let the skill access environment data more broadly than intended, increasing the chance of credential exposure or misuse if later code or prompts are unsafe.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest clearly configures an automated trader via an API key, managed entrypoint, and tunable position-sizing/risk parameters, but it does not warn users that enabling the skill can place real trades automatically. This is dangerous because users may supply credentials or start the automaton without understanding that it can take market positions and incur financial loss within the configured limits.

Content

No source excerpt is available for this finding.