Back to skill

Security audit

Polymarket Macro Weather Commodity Trader

Security checks for vulnerabilities and agentic risk

Overview

This skill is a clearly described trading bot, but its live-trading safeguards are weaker than documented and could expose real funds to unintended risk.

Install only if you are comfortable reviewing and fixing the trading controls before using live mode. Keep it in paper mode unless the SDK dependency is pinned and the volume, slippage/context, and account-position limits are enforced against real account state. Use a restricted API key and small limits for any live testing.

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:3
Finding

Unpinned Trading SDK Creates Supply-Chain Exposure

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:414
Finding

Configured Minimum Market Volume Safeguard Is Not Enforced

Content
View full analysis
= MAX_POSITIONS: break q = getattr(cm, "question", "") if not commodity_matches_stress(q, stress_dir): continue side, size, reasoning = compute_signal(cm, agg_stress, stress_dir) if not side: safe_print(f" [skip] {reasoning}") continue market_id = getattr(cm, "id", None) ok, why = context_ok(client, market_id) if not ok: safe_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, ) ``` ### Technical Analysis `SIMMER_MIN_VOLUME` is documented as a minimum market-volume filter, loaded into `MIN_VOLUME`, and printed at startup. It is never applied during market discovery, signal calculation, or the final pre-trade checks. Consequently, a market can reach `client.trade()` regardless of whether its volume is below the configured threshold. This violates the stated risk model and exposes live orders to thin or manipulable markets. The validation should fail closed when volume information is absent or ...[truncated 1102 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:310
Finding

Trading Context Safeguard Fails Open on Errors

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 intended to block flip-flop trades and trades with more than 15% estimated slippage. However, both an empty context response and any exception produce an approval result. Exceptions can arise from network failures, authentication problems, SDK behavior changes, malformed response objects, unexpected field types, or temporary service outages. Because the caller treats `True` as authorization to continue, failure of the risk-control service disables the safeguard instead of stopping the order. The issue is especially significant in live mode, where the same code path can authorize real trades. ### Attack Path 1. A commodity market produces an actionable signal. 2. The script calls `client.get_market_context(market_id)`. 3. The context request fails, or the returned data causes an exception while being parsed. 4. The exception is caught and only printed. 5. `context_ok()` returns `(True, "ok")`. 6. The caller proceeds to `client.trade()`. 7. The trade exe ...[truncated 608 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:413
Finding

Maximum Position Limit Counts Only Orders Placed During the Current Run

Content
View full analysis
= MAX_POSITIONS: break q = getattr(cm, "question", "") if not commodity_matches_stress(q, stress_dir): continue side, size, reasoning = compute_signal(cm, agg_stress, stress_dir) if not side: safe_print(f" [skip] {reasoning}") continue market_id = getattr(cm, "id", None) ok, why = context_ok(client, market_id) if not ok: safe_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}" safe_print(f" [trade] {side.upper()} ${size} {tag} {status} - {reasoning[:110]}") if r.success: placed += 1 except Exception as e: safe_print(f" [error] {market_id}: {e}") if placed >= MAX_POSITIONS: break ``` ### Technical Analysis `SIMMER_MAX_POSITIONS` is documented as the maximum number of concurrent open positions. The implementation instead initializes `placed` to zero on every invocation and increments it for each successful order in that invocation. The code does not query existing positions, determine whether a new order increases an existing position, or account ...[truncated 1391 chars]
Remediation
View remediation
Vulnerability Patterns
  • 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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (1)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill references a high-value environment credential (SIMMER_API_KEY) and trading functionality, but it does not declare any explicit tool scope or allowed-tools boundary. In an agent runtime, this can grant broader-than-necessary access to environment data and make it harder to enforce least privilege, increasing the chance of credential exposure or misuse if the skill is modified or composed with other capabilities.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.