Back to skill

Security audit

polymarket-mert-sniper

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed trading skill, but its managed defaults can materially change the live trading risk from what the documentation promises.

Review this before installing or enabling managed execution. The skill can place real trades when live mode is used, and the ClawHub tunables currently advertise higher and different defaults than the README and Python code. Use a dedicated low-balance wallet/API key, keep dry-run until you verify the exact configured values, and avoid exposing portfolio/status output in shared terminals or logs.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
clawhub.json:32
Finding

Managed automation defaults conflict with documented trading safeguards

Content
View full analysis

Vulnerability Details

File Location: clawhub.json:32-81
Additional Relevant Locations: SKILL.md:4, SKILL.md:50-54, mert_sniper.py:40-43, mert_sniper.py:511-522
Vulnerability Type: Unsafe financial automation configuration
Risk Level: High

Vulnerable Code

json
{
  "env": "SIMMER_MERT_MAX_BET_USD",
  "type": "number",
  "default": 50,
  "range": [
    1,
    200
  ],
  "step": 5,
  "label": "Max bet per trade"
},
{
  "env": "SIMMER_MERT_EXPIRY_MINUTES",
  "type": "number",
  "default": 30,
  "range": [
    5,
    120
  ],
  "step": 5,
  "label": "Order expiry (minutes)"
},
{
  "env": "SIMMER_MERT_MIN_SPLIT",
  "type": "number",
  "default": 0.1,
  "range": [
    0.01,
    0.5
  ],
  "step": 0.01,
  "label": "Minimum probability split"
},
{
  "env": "SIMMER_MERT_MAX_TRADES_PER_RUN",
  "type": "number",
  "default": 5,
  "range": [
    1,
    20
  ],
  "step": 1,
  "label": "Max trades per run"
},
{
  "env": "SIMMER_MERT_SIZING_PCT",
  "type": "number",
  "default": 0.1,
  "range": [
    0.01,
    1.0
  ],
  "step": 0.01,
  "label": "Position sizing percentage"
}

The conflicting implementation defaults and affected selection logic are:

python
CONFIG_SCHEMA = {
    "market_filter": {"env": "SIMMER_MERT_FILTER", "default": "", "type": str},
    "max_bet_usd": {"env": "SIMMER_MERT_MAX_BET_USD", "default": 10.00, "type": float},
    "expiry_window_mins": {"env": "SIMMER_MERT_EXPIRY_MINUTES", "default": 8, "type": int},
    "min_split": {"env": "SIMMER_MERT_MIN_SPLIT", "default": 0.60, "type": float},
    "max_trades_per_run": {"env": "SIMMER_MERT_MAX_TRADES_PER_RUN", "default": 5, "type": int},
    "sizing_pct": {"env": "SIMMER_MERT_SIZING_PCT", "default": 0.05, "type": float},
}
python
# Check split threshold
if price < MIN_SPLIT and price > (1 - MIN_SPLIT):
...[truncated 3345 chars]
Remediation
View remediation

Remediation Suggestions

  1. Align all metadata defaults with the documented and implementation defaults:

    • SIMMER_MERT_MAX_BET_USD: 10
    • SIMMER_MERT_EXPIRY_MINUTES: 8
    • SIMMER_MERT_MIN_SPLIT: 0.60
    • SIMMER_MERT_SIZING_PCT: 0.05
  2. Change the minimum-split range to [0.5, 1.0], or to a narrower reviewed range such as [0.5, 0.95].

  3. Reject unsafe values after configuration loading rather than relying solely on UI metadata:

    python
    if not 0.5 <= MIN_SPLIT < 1.0:
        raise ValueError("min_split must be between 0.5 and 1.0")
    if MAX_BET_USD <= 0:
        raise ValueError("max_bet_usd must be positive")
    if EXPIRY_WINDOW_MINS <= 0:
        raise ValueError("expiry_window_mins must be positive")
    
  4. Determine the favored side independently of the threshold:

    python
    if max(price, 1 - price) < MIN_SPLIT:
        continue
    
    side = "yes" if price >= 0.5 else "no"
    side_price = max(price, 1 - price)
    
  5. Add tests covering boundary and invalid values, including 0.10, 0.49, 0.50, 0.60, and values outside [0, 1].

  6. Add an integration test confirming that clawhub.json, SKILL.md, and CONFIG_SCHEMA expose identical defaults.

  7. Require an explicit confirmation when metadata increases live exposure beyond the documented default.

T08 · Insecure Dependencies

Warning
Location
clawhub.json:4
Finding

Privileged trading dependency is not pinned to an audited release

Content
View full analysis

Vulnerability Details

File Location: clawhub.json:4-11
Additional Relevant Location: SKILL.md:34-38
Vulnerability Type: Unconstrained privileged third-party dependency
Risk Level: Medium

Vulnerable Code

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

The installation instructions are even less restrictive:

markdown
1. **Install the Simmer SDK**
   ```bash
   pip install simmer-sdk
   ```

The dependency is imported and entrusted with credentials and live trading operations:

python
from simmer_sdk.skill import load_config, update_config, get_config_path
from simmer_sdk.guards.news_recency_veto import load_macro_news_schedule, news_window_match
python
from simmer_sdk import SimmerClient
python
_client = SimmerClient(api_key=api_key, venue=venue, live=live)
python
result = client.trade(
    market_id=market_id,
    side=side,
    amount=amount,
    source=TRADE_SOURCE, skill_slug=SKILL_SLUG,
    reasoning=reasoning,
    order_type=ORDER_TYPE,
)

Technical Analysis

The package requirement simmer-sdk>=0.17.25 allows pip to install any later compatible version. The documented pip install simmer-sdk command allows any version selected by the package resolver. Neither mechanism records an audited artifact hash.

This dependency is security-critical rather than a passive utility. It is imported during program startup and is delegated responsibility for:

  • Reading and applying configuration
  • Authenticating with SIMMER_API_KEY
  • Potentially using WALLET_PRIVATE_KEY for client-side order signing
  • Performing preflight checks
  • Redeeming positions
  • Retrieving portfolio and market information
  • Submitting live trades

Python package initialization code executes in the Skill's process and inherits its environment. A malic ...[truncated 1974 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin the dependency to a specifically reviewed release:

    json
    "pip": [
      "simmer-sdk==0.17.25"
    ]
    
  2. Use a lock file with cryptographic hashes, such as a hash-locked requirements file generated for each supported platform.

  3. Install with hash enforcement:

    bash
    pip install --require-hashes -r requirements.txt
    
  4. Update SKILL.md so users install from the same locked dependency specification rather than using an unconstrained command.

  5. Document the expected package index and prohibit untrusted extra indexes to reduce dependency-confusion exposure.

  6. Review SDK release notes and source changes before updating the pin.

  7. Run the Skill with a minimal environment:

    • Inject WALLET_PRIVATE_KEY only for live self-custody operation.
    • Avoid exposing unrelated credentials.
    • Use a dedicated wallet with bounded funds.
  8. Where supported, use scoped API credentials and server-side trading limits so compromise of the client dependency cannot authorize unlimited activity.

Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

This finding indicates a broad description-behavior mismatch where the skill advertises a near-expiry trading strategy but may instead perform account-status reporting and use a different API/account workflow than described. Such inconsistencies undermine user consent and make it hard to reason about what credentials, permissions, and financial actions the skill will actually perform.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This finding indicates a broad description-behavior mismatch where the skill advertises a near-expiry trading strategy but may instead perform account-status reporting and use a different API/account workflow than described. Such inconsistencies undermine user consent and make it hard to reason about what credentials, permissions, and financial actions the skill will actually perform.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill description says it should trade against the under-priced side, but this block explicitly selects the favorite when price >= MIN_SPLIT and otherwise buys NO, which still corresponds to backing the favorite. In a live trading skill, strategy/implementation mismatch is security-relevant because users may authorize capital based on the documented behavior while the code deploys funds in the opposite direction, causing systematic unintended losses and violating operator intent.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The nearby comment/documentation indicates one trading intent, but the actual branch logic does the opposite by backing the favorite. This is dangerous in an automated trading context because operators may trust the comment and enable --live, resulting in capital being deployed under a false understanding of the bot’s behavior.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The file is materially inconsistent with the declared skill purpose: instead of near-expiry Polymarket trading logic, it authenticates to a different service (Simmer) and retrieves account data. That mismatch is dangerous because users may grant secrets and run the skill expecting one platform/purpose, while the code accesses unrelated financial account information, expanding trust boundaries and enabling unauthorized data collection.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The embedded documentation identifies the module as 'Simmer Account Status' while the manifest presents a Polymarket trading skill, which is a strong signal of repackaging or deceptive functionality. In security-sensitive financial tooling, this context mismatch makes the code more dangerous because it can mislead reviewers and operators about what credentials will be used and what external systems will be contacted.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill documentation indicates capabilities that require access to environment variables and outbound network calls, including API keys and wallet private keys, but it does not explicitly declare any tool scope or permission boundaries. In an agent setting, missing scope declarations can cause the skill to be granted broader access than users expect, especially because it handles sensitive credentials and can initiate account-affecting actions.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The documentation states the strategy trades against the under-priced side, while the operational description says it buys the favored side. In a financial trading skill, this ambiguity is materially risky because it changes the market thesis and risk profile, and could cause users to deploy capital under the opposite strategy from what they intended.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The example output demonstrates buying the higher-probability side, contradicting earlier claims that the skill trades against the under-priced side. Examples are often what users rely on operationally, so contradictory examples can mislead them into approving a strategy they do not understand, particularly when live trading is available.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest configures an automated trading skill with tunable bet sizing, trade frequency, and live trading capability, but it does not present any explicit financial-risk or order-placement warning to the user. In this context, users may enable a strategy that places real-money trades without clearly understanding loss exposure, execution effects, or the consequences of switching from dry-run to live mode.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script reads broad portfolio, balance, concentration, PnL, and detailed position data that are unrelated to the advertised near-expiry sniper behavior. Even though it only prints the data locally, collecting and exposing unnecessary financial account details increases sensitivity and can leak private trading information through logs, terminals, CI output, cron logs, or shared execution environments.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.