Back to skill

Security audit

Polymarket Mispricing Events

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed automated trading bot, but its live-trading authority is paired with weak matching and fail-open safety checks that users should review carefully before installing.

Install only if you intend to run an automated prediction-market trader and are comfortable granting a Simmer API key that can place scheduled trades. Use the sim venue first, avoid live credentials until fail-closed portfolio/context checks and stronger market matching are fixed, and consider pinning dependencies before deployment.

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
mispricing_events.py:123
Finding
Market Safety Validation Fails Open When Context Retrieval Fails<![CDATA[ ## Vulnerability Details **File Location**: `mispricing_events.py:123-126` **Vulnerability Type**: Fail-open safety control **Risk Level**: High ```python except Exception: return True, "context unavailable" ``` ### Technical Analysis The `check_context` function is intended to prevent trades when the SDK reports severe flip-flop behavior, excessive slippage, or insufficient edge. However, every exception raised while retrieving or processing that context is caught and converted into an affirmative trading decision. This violates the fail-closed principle for a financial operation. Context retrieval failure does not establish that a trade is safe, particularly when `TRADING_VENUE` may be set to `live`. The broad `Exception` handler also conceals malformed responses, SDK defects, authentication failures, and programming errors. ### Attack Path 1. The Skill identifies a candidate trade. 2. An attacker or operational failure disrupts the Simmer context request, causes a timeout, or produces a malformed response. 3. `client.get_market_context()` or subsequent response processing raises an exception. 4. The exception handler returns `(True, "context unavailable")`. 5. The main loop treats the safety check as successful and proceeds to submit the trade without validated slippage, flip-flop, or edge information. ### Impact Assessment This does not independently grant new system privileges, but it bypasses safeguards controlling an authenticated trading capability. In live mode, it can result in real-money trades under unsafe market conditions, including excessive slippage or unstable trading behavior. The scope is limited by the account permissions associated with `SIMMER_API_KEY`, configured trade-size caps, and available trading capital. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Fail closed whenever market context cannot be retrieved or validated: ```python except Exception as exc: log.warning("Context validation failed for %s: %s", market_id, exc) return False, "context unavailable" ``` - In live mode, require successful validation of all mandatory controls before permitting a trade. - Catch narrowly defined SDK, timeout, JSON-decoding, and schema-validation exceptions rather than all exceptions. - Validate the types and expected ranges of `slippage_pct`, recommendations, and warning fields. - Add tests confirming that network errors, malformed responses, and SDK exceptions always prevent trade submission. - Consider allowing an explicitly configured fail-open policy only for paper trading, never as the default. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
mispricing_events.py:389
Finding
Portfolio Retrieval Failure Resets Position and Capital Safety State<![CDATA[ ## Vulnerability Details **File Location**: `mispricing_events.py:389-399` **Vulnerability Type**: Fail-open portfolio and position-limit enforcement **Risk Level**: High ```python # Get current portfolio state try: portfolio = client.get_portfolio() capital = float(portfolio.get("sim_balance", 100.0)) positions = client.get_positions() open_count = len([p for p in positions if not p.resolved]) if positions else 0 except Exception as e: log.warning(f"Portfolio fetch failed: {e}") capital = 100.0 open_count = 0 ``` ### Technical Analysis If either portfolio or position retrieval fails, the Skill assumes a balance of `$100` and zero open positions. The main loop subsequently uses these values for Kelly sizing and enforcement of `MAX_POSITIONS`. Unknown account state is therefore treated as available capacity. This can bypass the position limit and cause sizing based on fabricated capital. The issue is especially consequential in live mode because the code does not distinguish simulated balance from live balance and does not stop trading when authoritative portfolio state is unavailable. ### Attack Path 1. The Skill starts its scheduled trading cycle. 2. The portfolio or positions request fails because of a network interruption, SDK error, malformed response, authentication issue, or service outage. 3. The broad exception handler sets `capital = 100.0` and `open_count = 0`. 4. The `open_count >= MAX_POSITIONS` guard is evaluated using the fabricated zero count. 5. The scanner finds candidate signals and computes position sizes using the fabricated capital value. 6. Trades are submitted even if the account already has the maximum number of positions or lacks the assumed available capital. ### Impact Assessment The vulnerability can bypass account-level risk controls within the Skill. It may create positions beyond the configured maximum, produce incorrect Kelly sizing, ...[truncated 188 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Abort the trading cycle whenever portfolio balance or open-position state cannot be retrieved. - Do not use fabricated portfolio values as operational fallbacks: ```python except Exception as exc: log.error("Portfolio state unavailable; refusing to trade: %s", exc) return ``` - Retrieve and validate live and simulated balances through venue-appropriate fields. - Separate portfolio and position retrieval so each failure is logged precisely, while requiring both to succeed before trading. - Validate that balance is finite and non-negative and that the positions response has the expected schema. - Calculate available capacity from authoritative account state immediately before each trade to reduce race conditions. - Add tests proving that any portfolio or position retrieval failure results in zero submitted trades. ]]>

T08 · Insecure Dependencies

Warning
Location
clawhub.json:5
Finding
Security-Critical Runtime Dependencies Are Not Version or Integrity Pinned<![CDATA[ ## Vulnerability Details **File Location**: `clawhub.json:5` **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Medium ```json "pip": ["simmer-sdk", "requests", "urllib3"], ``` ### Technical Analysis The Skill installs `simmer-sdk`, `requests`, and `urllib3` without version constraints or package hashes. Installation can therefore resolve to any future version available from the configured package index. This is particularly sensitive for `simmer-sdk`: the Skill passes `SIMMER_API_KEY` to `SimmerClient`, and the SDK performs authenticated portfolio queries and trade submissions. A compromised, substituted, or unexpectedly incompatible release could access the credential, change transaction behavior, or execute arbitrary code with the Skill's runtime permissions. No malicious dependency is proven to be present in the reviewed package. The vulnerability is the absence of reproducible and integrity-verified dependency resolution. ### Attack Path 1. A dependency publisher account or package index is compromised, or an unsafe future package release is published. 2. The managed Skill environment performs a fresh installation using the unpinned package names. 3. The resolver selects the compromised or incompatible release. 4. Package installation or import executes attacker-controlled code. 5. In the case of `simmer-sdk`, the dependency can receive or access `SIMMER_API_KEY`, observe portfolio information, and manipulate authenticated trading operations. ### Impact Assessment A compromised dependency could execute code with the same filesystem, environment, and network privileges as the Skill. It could potentially read the Simmer API credential, disclose account information, alter or initiate trades, and access other data available to the process. The exact scope depends on the runtime sandbox and permissions attached to the API key. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions - Pin every dependency to a reviewed exact version. - Use a lockfile or installation mechanism that supports cryptographic hashes. - Verify that `simmer-sdk` is the official package from the expected publisher and review its source and release provenance. - Use a private or allowlisted package repository where possible. - Run dependency vulnerability and provenance scanning in CI. - Automate dependency updates through reviewed pull requests rather than resolving unrestricted versions during deployment. - Restrict runtime environment and network access so dependencies receive only the permissions required for declared trading functionality. ]]>
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 (7)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill is presented as a market-analysis strategy, but its behavior also includes trade execution, portfolio/position access, and market lookup through SimmerClient without corresponding declared permissions. That mismatch is dangerous because users may authorize what appears to be read-only analysis while the skill can perform state-changing financial actions and access account context.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill declares no explicit tool scope or permissions even though its documented behavior depends on environment-variable access and network/API access. In an agent system, missing capability declarations weaken reviewability and policy enforcement, making it easier for a skill to use sensitive resources without clear operator consent.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The module claims an edge based on consensus of 2+ prediction markets, but the trading logic permits execution with confidence >= 1, meaning one external source is enough. This mismatch is dangerous because operators may believe the strategy has stronger validation than it actually does, increasing the chance of unsafe autonomous trades based on thin evidence.

External Transmission

Medium
Category
Data Exfiltration
Content
# API endpoints
GAMMA_URL   = "https://gamma-api.polymarket.com"
CLOB_URL    = "https://clob.polymarket.com"
KALSHI_URL  = "https://api.elections.kalshi.com/trade-api/v2"
MANIFOLD_URL = "https://api.manifold.markets/v0"

# Caches (in-process, reset each run)
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
GAMMA_URL   = "https://gamma-api.polymarket.com"
CLOB_URL    = "https://clob.polymarket.com"
KALSHI_URL  = "https://api.elections.kalshi.com/trade-api/v2"
MANIFOLD_URL = "https://api.manifold.markets/v0"

# Caches (in-process, reset each run)
_kalshi_cache  = None
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The skill description says trades should be confirmed by at least one external platform, but the implementation accepts a single fuzzy-matched external market with a low similarity threshold and immediately treats it as confirmation. In an automated trading agent, weak entity matching can cause the bot to trade unrelated or only loosely related markets, creating avoidable financial loss from false signals.

Missing User Warnings

Medium
Confidence
79% confidence
Finding
This code file places live or simulated trades automatically via `client.trade(...)`, which is a safety-critical operation affecting portfolio state. While the module docstring describes the bot's trading purpose and runtime logs record activity, there is no explicit user confirmation or caution in this file warning that execution will submit trades when signals are found.

Static analysis

No suspicious patterns detected.