Back to skill

Security audit

Polymarket Bundle Crypto Hourly Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed automated trading skill, but its paper-trading boundary and risk controls are weak enough that users should review it before using live funds.

Install only if you understand that this skill can trade with real funds when run live. Use a least-privilege or sandbox credential where possible, keep autostart disabled until reviewed, avoid reusing the same long-running process for live and paper runs, and do not rely on the documented volume or concurrent-position limits without fixing or independently verifying them.

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)

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:45
Finding

Paper-mode invocation can reuse a cached live trading client

Content
View full analysis
SimmerClient: global _client, MAX_POSITION, MIN_VOLUME, MAX_SPREAD, MIN_DAYS, MAX_POSITIONS global YES_THRESHOLD, NO_THRESHOLD, MIN_TRADE, MIN_SUB_INTERVALS if _client is None: venue = "polymarket" if live else "sim" _client = SimmerClient( api_key=os.environ["SIMMER_API_KEY"], venue=venue, ) if live: _client.live = True try: _client.apply_skill_config(SKILL_SLUG) except AttributeError: pass # apply_skill_config only available in Simmer runtime MAX_POSITION = float(os.environ.get("SIMMER_MAX_POSITION", str(MAX_POSITION))) MIN_VOLUME = float(os.environ.get("SIMMER_MIN_VOLUME", str(MIN_VOLUME))) MAX_SPREAD = float(os.environ.get("SIMMER_MAX_SPREAD", str(MAX_SPREAD))) MIN_DAYS = int(os.environ.get( "SIMMER_MIN_DAYS", str(MIN_DAYS))) MAX_POSITIONS = int(os.environ.get( "SIMMER_MAX_POSITIONS", str(MAX_POSITIONS))) YES_THRESHOLD = float(os.environ.get("SIMMER_YES_THRESHOLD", str(YES_THRESHOLD))) NO_THRESHOLD = float(os.environ.get("SIMMER_NO_THRESHOLD", str(NO_THRESHOLD))) MIN_TRADE = float(os.environ.get( "SIMMER_MIN_TRADE", str(MIN_TRADE))) MIN_SUB_INTERVALS = int(os.environ.get( "SIMMER_MIN_SUB_INTERVALS", str(MIN_SUB_INTERVALS))) return _client ``` ### Technical Analysis The module stores a single `SimmerClient` in the global `_client` variable. The requested execution mode is used only when `_client` is initially created. Subsequent calls return the existing client without verifying that ...[truncated 1550 chars]
Remediation
View remediation
SimmerClient: venue = "polymarket" if live else "sim" if venue not in _clients: client = SimmerClient( api_key=os.environ["SIMMER_API_KEY"], venue=venue, ) client.live = live _clients[venue] = client return _clients[venue] ``` - Before every trade, assert that the client's effective venue and live status match the mode requested by `run`. - Derive displayed mode information from the validated client configuration rather than only from the caller-provided Boolean. - Add a regression test that invokes live mode followed by paper mode in the same process and verifies that the second trade is simulated. - Consider requiring an additional explicit confirmation or separately scoped credential for live trading. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
trader.py:394
Finding

Declared liquidity and concurrent-position safeguards are not enforced

Content
View full analysis
= MAX_POSITIONS: break market = opp[0] market_id = getattr(market, "id", None) if not market_id: continue side, size, reasoning = compute_signal(market, opp) if not side: safe_print(f" [skip] {reasoning}") continue 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}") ``` ### Technical Analysis `SIMMER_MIN_VOLUME` is docume ...[truncated 1898 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
clawhub.json:3
Finding

Security-sensitive trading SDK dependency is not version-pinned

Content
View full analysis
Remediation
View remediation
" ] ``` - Use a lockfile or constraints file that records all transitive dependency versions. - Require package hashes during installation, such as with pip's `--require-hashes`. - Install only from an approved package index and disable unexpected extra indexes. - Review the SDK's source, release provenance, and ownership before upgrades. - Perform upgrades through a controlled dependency-review process rather than automatically accepting the latest release. - Use a narrowly scoped API key with only the permissions needed for this strategy. - Where supported, use separate credentials for simulation and live trading and apply account-level spending or position limits. ]]>
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
88% confidence
Finding

The skill documents use of a high-value environment credential (SIMMER_API_KEY) but does not declare any explicit tool scope or permissions boundary. That creates an authorization gap: an agent or runtime may expose broader environment access than necessary, increasing the chance that secrets are unintentionally available to the skill or to other components it invokes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest requires a SIMMER_API_KEY and clearly describes automated trading behavior, but it does not provide any user-facing warning in the manifest about external network access, credential usage, or the fact that the skill can place trades. This creates a real trust and consent issue: users may supply a live trading credential without adequate disclosure of how it will be used, increasing the risk of unintended account activity or financial loss.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.