Back to skill

Security audit

Kalshi Politics Random Buyer Publish

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a dry-run trading planner, but it also installs an unattended 30-minute scheduled run that is not disclosed in the user instructions.

Review this before installing. The dry-run order behavior is reassuring, but the default package schedules recurring credentialed runs and may modify Simmer-side market indexing without per-run confirmation. Use only a narrowly scoped, revocable Simmer key, pin or audit the SDK, and remove or explicitly opt into the cron automaton before use.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T06 · System Persistence

Error
Location
clawhub.json:56
Finding

Undocumented Managed Execution Every 30 Minutes

Content
View full analysis

Vulnerability Details

File Location: clawhub.json:56-59
Vulnerability Type: Undocumented scheduled persistence
Risk Level: High

json
"cron": "*/30 * * * *",
"automaton": {
  "managed": true,
  "entrypoint": "trade_skill.py"
}

Technical Analysis

The Skill declares a managed scheduled task that executes trade_skill.py every 30 minutes. This recurring behavior is not disclosed in SKILL.md, which presents the Skill as a manually invoked, dry-run planning utility.

Every scheduled invocation initializes an authenticated SimmerClient, retrieves account and market information, and can call import_kalshi_market() when a selected market is not already indexed. Although the implementation does not place financial orders and explicitly rejects --live, importing a market is still a remote state-changing operation.

Persistent unattended execution exceeds the minimum privilege required to produce a trade plan on explicit user request. It also increases the duration and frequency with which the Skill and its third-party dependency have access to SIMMER_API_KEY.

Attack Path

  1. The hosting platform loads clawhub.json and honors the managed automaton configuration.
  2. The cron expression launches trade_skill.py every 30 minutes without a new user request.
  3. The platform supplies SIMMER_API_KEY to the process.
  4. The program creates an authenticated Simmer client and retrieves balance, market, and context data.
  5. For an unindexed candidate, the program invokes import_kalshi_market(), modifying remote Simmer state without per-run confirmation.
  6. Scheduled access continues until the automaton is explicitly disabled or removed.

Impact Assessment

The configuration provides cross-session recurring execution with access to the Simmer API credential. Its scope includes repeated authenticated account-data retrieval, market discovery, context queries, and remote market imports. ...[truncated 270 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove the cron and managed automaton configuration from the default package.
  • Require an explicit user invocation for each planning run.
  • If scheduling is a required feature, make it opt-in and clearly document its frequency, network activity, credential usage, and shutdown procedure.
  • Require explicit confirmation before remote state-changing operations such as import_kalshi_market().
  • Separate read-only planning from market import so the default workflow requires only read-only API permissions.
  • Use a narrowly scoped, revocable API key and document how users can disable the schedule and revoke the credential.
  • Add rate limits and an execution audit log for any intentionally scheduled mode.

T08 · Insecure Dependencies

Warning
Location
clawhub.json:4
Finding

Unpinned Third-Party SDK Receives a Sensitive API Credential

Content
View full analysis

Vulnerability Details

File Location: clawhub.json:4-6; related use at trade_skill.py:7-8 and trade_skill.py:125-128
Vulnerability Type: Unpinned privileged dependency
Risk Level: Medium

json
"requires": {
  "pip": ["simmer-sdk"],
  "env": ["SIMMER_API_KEY"]
}
python
from simmer_sdk import SimmerClient
from simmer_sdk.sizing import size_position
python
def get_client() -> SimmerClient:
    global _CLIENT
    if _CLIENT is None:
        _CLIENT = SimmerClient(api_key=os.environ["SIMMER_API_KEY"], venue="kalshi")
    return _CLIENT

Technical Analysis

The package requires simmer-sdk without an exact version, integrity hash, lockfile, or locally reviewable source. The dependency runs inside the Skill process and is explicitly given SIMMER_API_KEY. It also implements the network-facing client methods used for account briefing, market discovery, market import, and context retrieval.

Consequently, installation behavior and credential handling can change when the package resolver selects a newer release. A compromised upstream release, package-index account, distribution artifact, or dependency of the SDK would execute with the same environment and privileges as the Skill.

The repository itself contains no direct API-key logging or exfiltration. The risk arises because sensitive credential and network behavior is delegated to an unpinned dependency whose implementation is outside the audited project.

Attack Path

  1. The Skill environment installs simmer-sdk without an exact version or verified artifact hash.
  2. A malicious or compromised compatible release is selected by the package resolver.
  3. Python imports the package when trade_skill.py starts, allowing package initialization code to execute.
  4. The program passes SIMMER_API_KEY to the dependency's SimmerClient constructor.
  5. A compromised SDK can read the process environment, transmit t ...[truncated 717 chars]
Remediation
View remediation

Remediation Suggestions

  • Pin simmer-sdk to an audited exact version rather than accepting arbitrary future releases.
  • Use a hash-locked dependency file, such as a requirements lock containing verified distribution hashes.
  • Verify package provenance, publisher identity, and release signatures where supported.
  • Review the SDK source and its transitive dependencies, particularly client initialization, authentication, telemetry, logging, and endpoint selection.
  • Run the Skill in a restricted environment with minimal filesystem access and outbound network access limited to documented Simmer endpoints.
  • Supply a least-privilege, read-only API credential for dry-run planning.
  • Avoid passing credentials to components that are unnecessary for the planning operation.
  • Add automated dependency vulnerability and integrity monitoring before accepting upgrades.
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 43)May include surrounding context.

md
- `SKILL.md`

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill references environment-variable access (SIMMER_API_KEY and strategy config) but does not declare an explicit tool scope such as permissions or allowed-tools. In agent platforms, missing scope declarations can cause overbroad runtime access or make the skill’s data-access expectations opaque, increasing the chance of unintended secret exposure or policy bypass if the runner grants default capabilities.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · trade_skill.py (reported line 144)May include surrounding context.

python
def read_value(item: Any, key: str, default: Any = None) -> Any:
    if isinstance(item, dict):
        return item.get(key, default)
    return getattr(item, key, default)


def format_probability(value: float) -> str:

Static analysis

No suspicious patterns detected.