Back to skill

Security audit

Polymarket Weather Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent weather-trading skill, but it needs review because it can automate real-money trades while asking for a wallet private key and relying on weak live-trading safeguards.

Install only if you are comfortable giving this skill and its SDK financial trading authority. Use a dedicated low-balance wallet, do not paste private keys into chat or logs, pin and review simmer-sdk before use, keep dry-run as the default, avoid --no-safeguards, and verify any automated schedule or automaton limits before enabling live trading.

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

Warning
Location
SKILL.md:69
Finding

Agent Workflow Requests and Exposes a Wallet Private Key Through the Process Environment

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:69-72
Vulnerability Type: Sensitive credential handling
Risk Level: Medium

Vulnerable Code

markdown
2. **Ask for wallet private key** (required for live trading)
   - This is the private key for their Polymarket wallet (the wallet that holds USDC)
   - Store in environment as `WALLET_PRIVATE_KEY`
   - The SDK uses this to sign orders client-side automatically — no manual signing needed

Related troubleshooting instructions at SKILL.md:261-265 reinforce this design:

markdown
- `WALLET_PRIVATE_KEY` is not set in the environment
- The SDK signs orders automatically when this env var is present — no manual signing code needed
- Fix: `export WALLET_PRIVATE_KEY=0x<your-polymarket-wallet-private-key>`
- Do NOT attempt to sign orders manually or modify the skill code — the SDK handles it

Technical Analysis

The setup workflow directs the AI Agent to ask the user for a raw wallet private key and store it in an environment variable. A wallet private key is a high-impact bearer secret: possession normally permits signing transactions for the corresponding wallet without additional authorization.

Local signing is relevant to live Polymarket trading, but involving the Agent in raw-key collection exceeds the safest minimum-privilege design. A secret placed in the process environment may be accessible to inherited child processes, third-party libraries, diagnostic tools, crash reporters, or other processes operating under the same account, depending on the runtime and operating-system configuration.

The audited project does not directly read or transmit WALLET_PRIVATE_KEY. Its documentation states that the external simmer-sdk consumes the variable for client-side signing. Therefore, this finding concerns unsafe credential handling and delegation, not confirmed exfiltration by the project code.

Attack Path

  1. A user follows t ...[truncated 938 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not request wallet private keys through an AI conversation or ordinary Agent setup workflow.
  • Integrate with an isolated signer, hardware wallet, delegated signing service, or wallet-provider API.
  • If local signing is unavoidable, accept the key through a protected secret manager or interactive no-echo prompt rather than chat or ordinary configuration.
  • Use a dedicated, low-value trading wallet with narrowly limited funds and token approvals.
  • Prevent secret inheritance by unrelated child processes and isolate the signer from nonessential dependencies.
  • Ensure logs, exception reports, telemetry, shell history, and configuration displays always redact secrets.
  • Document wallet-key rotation, revocation, incident response, and fund-migration procedures.

T08 · Insecure Dependencies

Warning
Location
clawhub.json:3
Finding

Unpinned Third-Party SDK Has Access to Trading Credentials and Order Execution

Content
View full analysis

Vulnerability Details

File Location: clawhub.json:3-10
Vulnerability Type: Unpinned security-sensitive dependency
Risk Level: Medium

Vulnerable Code

json
"requires": {
  "env": [
    "SIMMER_API_KEY"
  ],
  "pip": [
    "simmer-sdk"
  ]
},

The dependency is imported and given authenticated trading authority at weather_trader.py:42 and weather_trader.py:101-115:

python
from simmer_sdk.skill import load_config, update_config, get_config_path
python
def get_client(live=True):
    """Lazy-init SimmerClient singleton."""
    global _client
    if _client is None:
        try:
            from simmer_sdk import SimmerClient
        except ImportError:
            print("Error: simmer-sdk not installed. Run: pip install simmer-sdk")
            sys.exit(1)
        api_key = os.environ.get("SIMMER_API_KEY")
        if not api_key:
            print("Error: SIMMER_API_KEY environment variable not set")
            print("Get your API key from: simmer.markets/dashboard -> SDK tab")
            sys.exit(1)
        venue = os.environ.get("TRADING_VENUE", "polymarket")
        _client = SimmerClient(api_key=api_key, venue=venue, live=live)
    return _client

Technical Analysis

The manifest declares simmer-sdk without an exact version, lockfile, or integrity hash. Package resolution can consequently select a future release that was not part of this audit.

This dependency is security-sensitive because it receives the Simmer API key, performs portfolio and market operations, and submits trades. The Skill documentation also states that the SDK consumes WALLET_PRIVATE_KEY to sign orders. Python package code executes within the host process and can access its environment, filesystem permissions, and network access.

No evidence establishes that the current simmer-sdk package is malicious. The vulnerability is the uncontrolled supply-c ...[truncated 1207 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin simmer-sdk to an exact audited version.
  • Use a lockfile and require package hashes during installation.
  • Verify package publisher identity, release provenance, and signed artifacts where available.
  • Review the resolved SDK and its transitive dependencies before deployment.
  • Run trading functionality in an isolated environment with only the necessary files, credentials, and network destinations.
  • Separate wallet signing from market analysis and API access so the general SDK process does not receive unrestricted private-key access.
  • Establish a controlled dependency-update process that includes security review and regression testing before changing the pinned version.

T09 · Insecure Skill Coding Practices

Warning
Location
weather_trader.py:451
Finding

Live Trading Safeguards Fail Open When Market Context Retrieval Fails

Content
View full analysis

Vulnerability Details

File Location: weather_trader.py:451-481
Vulnerability Type: Fail-open financial safety control
Risk Level: Medium

Vulnerable Code

python
def get_market_context(market_id: str, my_probability: float = None) -> dict:
    """Get market context with safeguards and optional edge analysis."""
    try:
        if my_probability is not None:
            return get_client()._request("GET", f"/api/sdk/context/{market_id}",
                                         params={"my_probability": my_probability})
        return get_client().get_market_context(market_id)
    except Exception:
        return None


def get_price_history(market_id: str) -> list:
    """Get price history for trend detection."""
    try:
        return get_client().get_price_history(market_id)
    except Exception:
        return []


def check_context_safeguards(context: dict, use_edge: bool = True) -> tuple:
    """
    Check context for safeguards. Returns (should_trade, reasons).
    
    Args:
        context: Context response from SDK
        use_edge: If True, respect edge recommendation (TRADE/HOLD/SKIP)
    """
    if not context:
        return True, []  # No context = proceed (fail open)

Technical Analysis

get_market_context() catches every exception and converts it to None, discarding the reason for the failure. check_context_safeguards() then treats missing context as approval to proceed.

As a result, network failures, authentication errors, malformed responses, server faults, and SDK exceptions disable all context-dependent protections. These protections otherwise check for resolved markets, severe flip-flopping, short time to resolution, insufficient liquidity, excessive slippage, and unfavorable edge recommendations.

The fail-open decision applies to the common strategy path and is not restricted to simulated mode. When the program is invoked ...[truncated 1229 chars]

Remediation
View remediation

Remediation Suggestions

  • Fail closed in live mode whenever market context cannot be retrieved or validated.
  • Permit fail-open behavior only in explicitly selected dry-run or research mode.
  • Preserve and report the exception type and reason without exposing credentials.
  • Add bounded retries with exponential backoff for transient context failures.
  • Validate the context response schema before treating it as authoritative.
  • Return a structured result that distinguishes network failure, authentication failure, invalid response, and an actual empty context.
  • Require all mandatory safeguards to complete successfully before submitting a live order.
  • Add tests demonstrating that exceptions and malformed context responses prevent live buy and sell operations.
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description emphasizes weather-forecast-driven trading of Polymarket weather markets through Simmer, including automation and strategy execution. However, this code chunk only performs authenticated read-only account status checks against Simmer API endpoints (/api/sdk/portfolio and /api/sdk/positions). It displays balances, positions, PnL, and related portfolio information. There is no weather data access, no NOAA/Open-Meteo integration, no market selection logic, and no trade execution. This is a materially different primary purpose from the declared trading/forecasting functionality, so it should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents use of environment variables and external network APIs, including highly sensitive secrets like API keys and wallet private keys, but does not declare any tool scope or allowed-tools boundaries. In an agent setting, missing explicit permission declarations can cause overbroad execution authority and make secret access or network actions less visible to operators and policy systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation tells users to provide and store a wallet private key for live trading, but does not prominently warn that this key grants direct control over funds and must be handled as a highly sensitive secret. In an agent context, encouraging routine placement of a private key into the environment increases the chance of accidental disclosure via logs, shell history, prompts, crash reports, or overly broad tool access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill includes commands for live trading and even disabling safeguards, yet it does not present a clear, prominent warning that trades are financially risky and potentially irreversible. In a trading skill, omission of such warnings can cause unsafe operator behavior, especially when agents may automate execution and users may not appreciate that '--live' can move real funds immediately.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest requires a sensitive API credential and declares an automated trading entrypoint, yet it provides no user-facing disclosure that the skill can place trades or use externally supplied credentials to perform financial actions. In a trading skill, this omission is security-relevant because users may enable or invoke automation without clearly understanding that it can execute market transactions and consume privileged API access.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · weather_trader.py (reported line 189)May include surrounding context.

python
"Wellington": {"lat": -41.2866, "lon": 174.7756, "tz": "Pacific/Auckland"},
}

OPEN_METEO_BASE = "https://api.open-meteo.com/v1/forecast"

def get_openmeteo_forecast(city: str) -> dict:
    """Get Open-Meteo forecast for an international city.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill performs capability-expanding actions beyond passive forecast lookup and trade execution: it searches external Polymarket listings and imports markets into Simmer automatically. In a trading skill, this increases attack surface because untrusted external market metadata and URLs influence what gets onboarded and later considered for trading, potentially causing unintended market exposure or abuse of the user's account/API permissions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
73% confidence
Finding

The skill loads config from disk and later exposes a CLI path that updates config.json, creating persistent local state unrelated to the user-facing purpose described in the manifest. While operationally useful, local configuration mutation is not clearly justified by a description focused on weather-market trading and forecast checks.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
68% confidence
Finding

The manifest focuses on trading weather markets and checking forecasts, but this function retrieves current positions from the trading account and the CLI can print them. Portfolio/positions visibility may be useful operationally, yet it is an account-inspection capability not explicitly stated in the skill description.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.