Back to skill

Security audit

Kalshi Trader

Security checks for vulnerabilities and agentic risk

Overview

The skill is for Kalshi trading, but it asks an unattended agent to use local trading credentials for real-money actions without enough safeguards or user control.

Install only after treating this as live financial automation. Use a dedicated low-permission Kalshi key, prefer a sandbox or dry-run mode, set hard exposure and loss limits, keep research separate from order execution, and avoid running the cron job until credential storage, approvals, logging, and emergency shutdown are clearly configured.

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)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:12
Finding
Unpinned Dependencies Installed Outside the System Package Manager’s Protections## Vulnerability Details **File Location**: `SKILL.md`, lines 12-16 **Vulnerability Type**: Supply-chain exposure through unpinned dependencies and forced global installation **Risk Level**: Medium **Vulnerable code snippet**: ```bash ### 1. Install dependencies pip install cryptography requests --break-system-packages ``` ### Technical Analysis The installation command retrieves the latest available versions of `cryptography` and `requests` without version constraints, hashes, a lock file, or an isolated virtual environment. Consequently, installations performed at different times may execute materially different third-party code than the code considered during this audit. The `--break-system-packages` option bypasses protections intended to prevent `pip` from modifying a Python environment managed by the operating system. If the command is executed with elevated privileges, a compromised dependency or installation hook could alter system-wide Python packages and affect unrelated applications. The package names are legitimate and there is no evidence that either dependency is currently malicious. The vulnerability is the unsafe installation model, which unnecessarily expands the consequences of an upstream package compromise or compromised package index. ### Attack Path 1. An attacker compromises a dependency release, one of its transitive dependencies, the configured Python package index, or the network/package-resolution environment. 2. A user follows the setup instructions at a time when the malicious or otherwise unsafe release is selected. 3. `pip` downloads and executes package build or installation code. 4. Because versions and hashes are not constrained, the malicious release is accepted without an integrity comparison against an audited artifact. 5. If installation occurs in a privileged or system-managed environment, `--break-system-packages` allows the installation to affect the system Python environment an ...[truncated 727 chars]
Remediation
## Remediation Suggestions - Create and use a dedicated virtual environment rather than modifying the system-managed Python environment. - Remove `--break-system-packages` from the documented installation command. - Pin direct and transitive dependencies to reviewed versions in a lock file. - Require package hashes, for example through a generated requirements file used with `pip install --require-hashes`. - Install dependencies as an unprivileged user and explicitly warn users not to run the command with `sudo`. - Use a controlled package index or dependency mirror where practical. - Add automated vulnerability and provenance checks for dependency updates. - Review and deliberately update dependency pins instead of automatically installing the newest release.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
references/cron-prompt.md:5
Finding
Research Agent Is Given Unnecessary Direct Knowledge of Financial API Credential Paths## Vulnerability Details **File Location**: `references/cron-prompt.md`, lines 5-22 **Vulnerability Type**: Excessive credential exposure and trading authority in an agent that processes untrusted web content **Risk Level**: High **Vulnerable code snippet**: ```text Kalshi 15-min review. API credentials at ~/.kalshi/key_id.txt and ~/.kalshi/private_key.pem. Base URL: https://api.elections.kalshi.com **RESEARCH:** Use web_fetch only (no web_search unless no known URL exists). Data sources: gasprices.aaa.com, whitehouse.gov/presidential-actions, api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd, wttr.in/CityName?format=3, congress.gov Steps: 1. Check each open position's current bid vs your fair value. Exit any at or above fair value (net of fees). 2. If any position dropped >15%, fetch relevant data URLs to check if fundamentals changed. Exit only if new evidence shows the outcome is unlikely. 3. Scan markets closing within 7 days (volume >500, spread <10%). For each candidate, fetch data from known URLs to estimate fair value. Calculate EV IRR. Place if >= 50%. ``` Related credential-loading code in `scripts/kalshi_bot.py`, lines 31-37: ```python with open(KEY_PATH, "rb") as f: _private_key = serialization.load_pem_private_key(f.read(), password=None) with open(KEY_ID_PATH) as f: _key_id = f.read().strip() ``` ### Technical Analysis The scheduled prompt explicitly discloses the locations of the Kalshi key identifier and unencrypted private key to an autonomous agent. The same agent is directed to fetch and interpret external web content and is authorized to make financial trading decisions. External pages are untrusted input. If retrieved content contains adversarial instructions and the agent fails to maintain a strict data/instruction boundary, that content could influence the agent to read, disclose, or misuse the credentials. The private key is loaded with `pass ...[truncated 2468 chars]
Remediation
## Remediation Suggestions - Remove credential paths and all key material references from prompts supplied to research-capable agents. - Separate research from execution. Have the research component return structured evidence and a proposed trade to a deterministic, narrowly privileged executor. - Place signing behind a local broker with an allowlisted API surface. The broker should validate ticker, side, order type, price, quantity, and maximum aggregate exposure before signing. - Use a dedicated Kalshi API credential with the narrowest available permissions and strict account-level spending limits. - Require explicit human approval for trades or at least for orders exceeding a small predefined threshold. - Treat all fetched web content strictly as data. Do not permit fetched pages to issue tool instructions, modify policy, access files, or select arbitrary URLs. - Allowlist research domains and validate redirects so trusted URLs cannot redirect the agent to attacker-controlled content. - Run the research agent and trade executor under separate operating-system identities or sandboxes. Only the executor should be able to access the signing key. - Prefer a hardware-backed or operating-system keystore-backed non-exportable key. If a PEM must be used, encrypt it at rest and avoid making its decryption secret available to the research process. - Add immutable audit logging, per-order limits, daily loss limits, rate limits, and immediate credential revocation procedures.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/kalshi_bot.py:39
Finding
API Requests Lack Timeouts, Status Validation, and Fail-Closed Error Handling## Vulnerability Details **File Location**: `scripts/kalshi_bot.py`, lines 39-56 **Vulnerability Type**: Unsafe handling of remote API failures **Risk Level**: Medium **Vulnerable code snippet**: ```python def signed_request(method, path, body=None): timestamp = str(int(time.time() * 1000)) msg = (timestamp + method + path.split("?")[0]).encode() sig = _private_key.sign( msg, padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.DIGEST_LENGTH), hashes.SHA256() ) headers = { "KALSHI-ACCESS-KEY": _key_id, "KALSHI-ACCESS-TIMESTAMP": timestamp, "KALSHI-ACCESS-SIGNATURE": base64.b64encode(sig).decode(), "Content-Type": "application/json" } if body: return requests.request(method, BASE + path, headers=headers, json=body) return requests.request(method, BASE + path, headers=headers) ``` Related unchecked response handling at lines 59-68: ```python def get_balance(): r = signed_request("GET", "/trade-api/v2/portfolio/balance") return r.json().get("balance", 0) / 100 def get_positions(): r = signed_request("GET", "/trade-api/v2/portfolio/positions?count_filter=position&limit=50") return r.json().get("market_positions", []) ``` ### Technical Analysis Every authenticated request is made without connection or read timeouts. A stalled endpoint can therefore block the bot indefinitely, causing scheduled executions to overlap or preventing monitoring and reporting. Responses are parsed without calling `raise_for_status()` or validating the response schema. Authentication failures, rate limits, server errors, and unexpected but valid JSON objects can consequently be interpreted as legitimate zero balances or empty positions. In `cmd_scan`, an empty position result means the `owned` set is empty, undermining the safeguard intended to skip markets already held. In trading- ...[truncated 2080 chars]
Remediation
## Remediation Suggestions - Specify explicit connection and read timeouts for every request, such as `timeout=(5, 20)`. - Call `raise_for_status()` before parsing response bodies. - Validate each successful response against the expected schema and data types; never replace an unknown account state with zero or an empty list. - Abort the trading cycle when balance, position, or market state cannot be verified. - Implement bounded retries with exponential backoff and jitter for safe, idempotent reads. - Do not blindly retry order submissions. Reconcile them using a unique `client_order_id` and query order status before resubmitting. - Introduce a process lock so delayed cron jobs cannot overlap. - Log sanitized HTTP status and error details without logging authentication headers or signatures. - Return explicit typed errors to the controlling agent so API failure cannot be interpreted as a valid “no positions” result.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description promises a fully automated trading system with research, scheduling, trade placement, monitoring, and reporting, but the analyzed behavior reportedly lacks most of those controls and automations. This mismatch is dangerous because users may grant trust, permissions, or real-money credentials based on claims that are not actually implemented or validated, creating unsafe operational assumptions.

Missing User Warnings

High
Confidence
96% confidence
Finding
The skill describes unattended scanning, trade decisions, credential setup, and scheduled execution for real-money trading but does not present a clear user-facing warning about financial risk, automation risk, or live order placement. In this context, omission of that warning materially increases the chance of users enabling autonomous market actions without informed consent or proper safeguards.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Cancel Order
```
DELETE /trade-api/v2/portfolio/orders/<order_id>
```

## Price Notes
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Missing User Warnings

High
Confidence
98% confidence
Finding
The prompt authorizes autonomous placement and exit of real trades based on model-driven rules, but provides no prominent warning, approval gate, or operational safeguard for real-money financial transactions. In this skill context, that is especially dangerous because the cron job is designed to run unattended every 15 minutes, so mistakes, prompt misinterpretation, bad data, or abuse could cause repeated financial losses.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill instructs users to write files under the home directory and perform network access to Kalshi and external research endpoints, but it does not declare any explicit tool scope such as allowed-tools or permissions. In an agent setting, undocumented file-write and network capability increases the chance of unintended credential handling, overbroad execution, or silent expansion of what the skill can do.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The manifest description says to use the skill when a user wants to "automate Kalshi trading, set up a prediction market bot, configure market scanning, or get daily P&L reports from Kalshi." Several of these triggers are broad capability descriptions rather than narrowly scoped invocation phrases, and the file provides no exclusion conditions or negative examples to limit unintended activation.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
### 2. Store Kalshi credentials
```bash
mkdir -p ~/.kalshi && chmod 700 ~/.kalshi
nano ~/.kalshi/private_key.pem   # paste -----BEGIN RSA PRIVATE KEY----- block
chmod 600 ~/.kalshi/private_key.pem
echo "YOUR-API-KEY-ID-HERE" > ~/.kalshi/key_id.txt
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
### 2. Store Kalshi credentials
```bash
mkdir -p ~/.kalshi && chmod 700 ~/.kalshi
nano ~/.kalshi/private_key.pem   # paste -----BEGIN RSA PRIVATE KEY----- block
chmod 600 ~/.kalshi/private_key.pem
echo "YOUR-API-KEY-ID-HERE" > ~/.kalshi/key_id.txt
Confidence
88% confidence
Finding
The skill directs users to persist long-lived Kalshi credentials under ~/.kalshi, creating durable session/authentication material on disk for an unattended trading bot. In the context of real-money trading automation, persistent local secrets increase the blast radius of host compromise, accidental reuse, backups leakage, or misuse by later processes.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
mkdir -p ~/.kalshi && chmod 700 ~/.kalshi
nano ~/.kalshi/private_key.pem   # paste -----BEGIN RSA PRIVATE KEY----- block
chmod 600 ~/.kalshi/private_key.pem
echo "YOUR-API-KEY-ID-HERE" > ~/.kalshi/key_id.txt
chmod 600 ~/.kalshi/key_id.txt
```
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
mkdir -p ~/.kalshi && chmod 700 ~/.kalshi
nano ~/.kalshi/private_key.pem   # paste -----BEGIN RSA PRIVATE KEY----- block
chmod 600 ~/.kalshi/private_key.pem
echo "YOUR-API-KEY-ID-HERE" > ~/.kalshi/key_id.txt
chmod 600 ~/.kalshi/key_id.txt
```
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
mkdir -p ~/.kalshi && chmod 700 ~/.kalshi
nano ~/.kalshi/private_key.pem   # paste -----BEGIN RSA PRIVATE KEY----- block
chmod 600 ~/.kalshi/private_key.pem
echo "YOUR-API-KEY-ID-HERE" > ~/.kalshi/key_id.txt
chmod 600 ~/.kalshi/key_id.txt
```
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

External Transmission

Medium
Category
Data Exfiltration
Content
- Gas prices: `https://gasprices.aaa.com/`
- Trump actions: `https://www.whitehouse.gov/presidential-actions/`
- Treasury yields: `https://home.treasury.gov/resource-center/data-chart-center/interest-rates/`
- Bitcoin/crypto: `https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd`
- Weather: `https://wttr.in/CityName?format=3`
- Congress bills: `https://www.congress.gov`
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation shows direct loading of a private signing key and key ID from fixed filesystem paths without any warning about secure secret storage, file permissions, or avoiding accidental exposure. In the context of an automated trading bot, these credentials authorize real-money account actions, so insecure handling materially increases the risk of credential theft and unauthorized trading.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The file documents live order placement and cancellation endpoints with concrete request shapes but provides no warning that these operations affect a real Kalshi account and can move funds or positions immediately. Because this skill is for fully automated trading, omission of safety guidance makes misuse more dangerous by encouraging unattended execution against production endpoints.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The prompt explicitly instructs the agent to read API credentials from fixed local filesystem paths, which creates a direct secret-access pattern inside an automated workflow. In an agent setting, this increases the chance of unauthorized credential use, accidental leakage through logs/tool output, or execution in an unintended environment where local secrets are present.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill directs access to sensitive local credential files without any disclosure, confirmation step, or warning that the agent will handle secrets. This is dangerous because users may invoke or deploy the skill without realizing it can consume privileged local materials and perform authenticated actions on their behalf.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This workflow gives concrete instructions for selecting and placing trades based on external research and confidence thresholds, but it omits any explicit warning that real-money trading can cause losses and that researched signals may be wrong. In the context of an automation skill for a prediction-market trading bot, that omission materially increases the chance that users will treat the guidance as safe-to-execute financial advice and enable unattended trading without understanding the risks.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The document provides explicit exit logic and sample order-construction details for selling positions, which could be directly operationalized in a live trading system, yet it does not warn that submitting orders may be irreversible or executed at unfavorable prices. Because this skill is specifically designed to automate Kalshi trading, the missing warning and safeguards make accidental or poorly understood real-money execution more dangerous than in a purely educational context.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script automatically loads a live private key and key ID from standard local paths at import time, creating immediate access to trading credentials without any user prompt or runtime disclosure. In the context of a trading bot, this is risky because merely running or importing the script can prepare it to authenticate to a financial API, increasing the chance of unintended credential use or exposure through dependent code paths.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This function performs authenticated requests to a live trading API using locally loaded signing credentials, yet the file provides no explicit warning, consent gate, or dry-run protection before such actions are available. In a financial-trading skill, undisclosed authenticated network capability is more dangerous because it can affect real accounts and positions if later invoked directly or reused by other code.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The manifest describes autonomous market research, execution based on EV/IRR and Kelly criteria, position monitoring, and Telegram reporting. In this file, the executable commands only test connectivity, scan/filter markets, and print a console summary; no command actually calls place_trade, no EV/IRR or Kelly sizing logic is implemented, and no Telegram messaging exists.

Intent-Code Divergence

Low
Confidence
79% confidence
Finding
The inline documentation presents the script as a scanner/summary/test utility, while the skill-level documentation describes a much more capable autonomous trading system. This creates an intent mismatch between documented purpose and implemented behavior in the analyzed file.

Static analysis

No suspicious patterns detected.