Back to skill

Security audit

Kalshi Eth Merge Momentum Trader

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed trading bot, but it asks for an apparently unused Solana wallet private key and has financial-safety and dependency-scope issues that warrant review before installation.

Install only after reviewing why a Solana private key is required, and avoid providing any wallet private key unless the publisher documents exactly which component uses it and why. Use dry-run mode first, pin or review the simmer-sdk version, keep credentials narrowly scoped and revocable, and treat --live as authority to place and close real trades.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
trader.py:324
Finding

Trading safeguards fail open when market context retrieval fails

Content
View full analysis
dict: """Get market context with safeguards and 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 check_safeguards(context: dict) -> tuple: """Check context for safeguards. Returns (should_trade, reasons).""" if not context: return True, [] ``` ### Technical Analysis The market-context function suppresses every exception and returns `None`. The safeguard function then interprets missing or empty context as authorization to continue trading. Consequently, all context-dependent controls are bypassed when context retrieval fails, including: - Resolved-market detection - Flip-flop and trading-discipline warnings - Minimum time-to-resolution enforcement - Minimum-liquidity enforcement - Maximum-slippage enforcement The behavior is security-sensitive because `check_safeguards()` is called immediately before `execute_trade()` in the live trading path. A network outage, malformed API response, SDK error, authentication failure, or service-side disruption therefore weakens rather than stops the system. ### Attack Path 1. The Skill identifies a signal that would result in a live order. 2. An attacker or operational failure disrupts the context endpoint, causes an invalid response, or otherwise makes `get_market_context()` raise an exception. 3. The exception is suppressed and the function returns `None`. 4. `check_safeguards(None)` returns `(True, [])`. 5. The Skill calls `execute_trade()` without validating ...[truncated 684 chars]
Remediation
View remediation
tuple: if not isinstance(context, dict) or not context: return False, ["Market context unavailable or invalid"] ``` - Do not suppress all exceptions silently. Catch expected SDK or network exceptions, record the error type, and stop the affected order. - Validate the structure and types of all security-relevant response fields before approving a trade. - Require successful checks for market status, time to resolution, liquidity, and slippage before every live order. - Consider bounded retries with exponential backoff for transient failures, but reject the order if retries are exhausted. - Add tests proving that timeouts, malformed JSON, authentication failures, empty responses, and missing fields all block live execution. ]]>

T08 · Insecure Dependencies

Warning
Location
clawhub.json:8
Finding

Unpinned third-party SDK receives a high-value trading credential

Content
View full analysis
SDK tab") sys.exit(1) venue = os.environ.get("TRADING_VENUE", "kalshi") _client = SimmerClient(api_key=api_key, venue=venue, live=live) return _client ``` ### Technical Analysis The package requirement does not specify an audited version, integrity hash, or lockfile. Installation may therefore resolve to a newer package release than the version originally reviewed. This dependency is security-sensitive because imported Python packages execute code in the Skill's process and can access its complete environment. The SDK also receives `SIMMER_API_KEY` directly and controls API requests and live trade submission. A compromised publisher account, malicious package release, or upstream repository compromise could consequently affect credentials and transactions without any change to this project. The reviewed project does not prove that the current `simmer-sdk` release is malicious. The vulnerability is the mutable and unverified trust boundary around a package with access to high-value credentials. ### Attack Path 1. An attacker compromises the upstream package publication channel ...[truncated 1171 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
clawhub.json:4
Finding

Solana private key is requested despite not being used by project code

Content
View full analysis
SDK tab") sys.exit(1) venue = os.environ.get("TRADING_VENUE", "kalshi") _client = SimmerClient(api_key=api_key, venue=venue, live=live) ``` ### Technical Analysis No code in `trader.py` reads `SOLANA_PRIVATE_KEY`, passes it to a function, or checks that it exists. Nevertheless, both installation metadata and documentation require users to place this high-value wallet secret in the process environment. Environment variables are visible to ordinary Python code executing in the same process, including imported dependencies and optional modules. Requiring an unused private key therefore expands the available privilege and secret scope without a demonstrated need in the reviewed implementation. This is especially significant because possession of a wallet private key is generally stronger authority than possession of a narrowly scoped trading API token. The declaration conflicts with least-privilege principles even though no direct private-key transmission or exfiltration was found in `trader.py`. ### Attack Path 1. A user follows the Skill metadata and exports `SOLANA_PRIVATE_KEY` before execution. 2. The private key becomes a ...[truncated 870 chars]
Remediation
View remediation
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 (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description understates the skill's effective behavior: the document reveals live trade execution, automated exit logic, position inspection, market discovery, and use of SOLANA_PRIVATE_KEY, none of which are fully represented in the top-level description/requirements. This mismatch is dangerous because users may grant credentials or enable --live under an incomplete understanding of the skill's authority, leading to unauthorized or unexpected financial actions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Declaring access to a Solana private key is an unjustified high-sensitivity capability for a Kalshi-focused ETH momentum trader. In this context, the mismatch is especially dangerous because private keys enable irreversible asset transfers, so any hidden code path, later update, or supply-chain compromise could use the credential to drain a wallet.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares access to sensitive environment variables (SIMMER_API_KEY, and later SOLANA_PRIVATE_KEY) but does not define any explicit tool scope or permissions boundary. In an automated trading skill, undeclared env access weakens least-privilege guarantees and makes it harder for operators to understand what secrets the skill may consume.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documentation contradicts the manifest by introducing an additional high-value credential (SOLANA_PRIVATE_KEY) not declared in requires_env. In security-sensitive trading workflows, inconsistent credential declarations can cause unsafe deployment decisions, accidental secret exposure, or bypass of review processes that rely on manifest metadata.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The manifest requests SOLANA_PRIVATE_KEY even though the skill metadata describes only Kalshi ETH market trading with SIMMER_API_KEY and simmer-sdk. Unnecessary access to a blockchain private key expands the secret exposure surface and could enable unrelated wallet actions if the skill code or dependencies are compromised.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill is presented as a Kalshi ETH trader, but its usage text states that live mode executes real trades via DFlow/Solana and requires a Solana private key. That broadens the operational scope from prediction-market trading to blockchain-linked execution, increasing the chance an operator supplies sensitive wallet credentials and enables unintended asset movement outside the declared purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The client chooses its trading venue from the TRADING_VENUE environment variable, even though the skill is described as Kalshi-specific. This allows external environment manipulation to redirect orders to an unintended venue, violating operator expectations and potentially changing account, market, and execution semantics without code changes.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The skill's stated purpose is to trade ETH price markets based on a thesis, but the CLI includes a --set path that persists configuration changes through update_config. Persistent local configuration mutation is ancillary operational capability rather than an obvious requirement of the declared trading function.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.