T01 · Skill Instruction Hijacking
Agent instructions require unauthorized source modification and Git staging
SKILL.md:197Security audit
Security checks for vulnerabilities and agentic risk
This skill mostly matches a Kalshi portfolio monitor, but it includes under-disclosed Slack transmission of sensitive portfolio alerts and agent instructions to persistently modify installed code.
Install only if you are comfortable giving it Kalshi API access, storing portfolio snapshots under ~/.openclaw/state, and reviewing or removing the Slack webhook and Agent Bug-Fix Protocol behavior first. Protect the Kalshi key file and avoid sharing debug output that prints credential values or portfolio state.
SKILL.md:197scripts/portfolio_drift.py:48scripts/portfolio_drift.py:299data=payload.encode("utf-8"),
headers={"Content-Type": "application/json"}
)
with urllib.request.urlopen(req, timeout=5) as response:
response.read()
except Exception:
# Notification failure should never crash the monitorThe Slack webhook destination is taken from an environment variable or local config and used directly for an outbound HTTP request without validation or allowlisting. In an agent/skill context, that creates an exfiltration channel: portfolio drift alerts and related trading metadata can be sent to any attacker-controlled URL if the environment or config is poisoned, and the broad exception handling makes this hard to detect.
Granting a portfolio drift monitor authority to edit Python source files and stage git commits is unjustified and materially expands its attack surface. If the skill is triggered in an agent context, those permissions could be abused to implant persistence, alter trading logic, or tamper with local repositories under the guise of bug fixing.
This markdown file tells users to obtain a Kalshi API key and set KALSHI_KEY_ID and KALSHI_KEY_PATH, but it does not include any caution about these being sensitive credentials or advice to protect them. Under the markdown-file criteria for missing user warnings, credential-related behavior that can affect privacy or account security should be disclosed.
The skill documents capabilities to access environment variables, write local state, and call external APIs, yet it declares no explicit tool or permission scope. That mismatch can cause the agent platform to grant broader powers than users expect, increasing the chance of unintended file, credential, or network access.
The skill notes persistent state storage, but it does not prominently warn that portfolio position data is written to disk in a local snapshot file. Users may not realize potentially sensitive trading information will persist across sessions and be available to other local processes or users depending on filesystem permissions.
The skill requires API credentials from environment variables and transmits portfolio data to Kalshi, but it lacks a clear privacy and credential-handling warning. Users may enable it without understanding that secrets are read from the environment and sensitive account data is sent over the network and processed locally.
Broad trigger phrases like 'portfolio alert' or 'kalshi positions' can cause accidental invocation during ordinary conversation. When combined with network access, credential use, and local persistence, unintended runs can expose sensitive data or create snapshots without clear user intent.
The documentation first describes a simple one-call monitoring utility, then later expands to code and git modification behavior. This inconsistency undermines informed consent and makes it easier for risky actions to be smuggled into a low-risk skill profile.
The skill is presented as a read-only portfolio monitor, but the later bug-fix protocol authorizes editing source files and modifying installed copies. This creates a dangerous documentation/behavior gap where an agent invoked for monitoring could persist unexpected changes to code on disk.
## Agent Bug-Fix Protocol **CRITICAL**: When you (the agent) discover and fix a bug in any script during a conversation, you MUST write the fix to the source file on disk using file editing tools. Showing the fix in chat is NOT sufficient — the next scheduled run starts a fresh session and will not have your conversational fix. Checklist after finding a bug: 1. Edit the actual `.py` file on disk (e.g., `~/skills/portfolio-drift-monitor/scripts/portfolio_drift.py`)
The instruction to write fixes directly to source files on disk creates persistence beyond the current session, which is unnecessary for a monitoring skill. In an adversarial or mistaken invocation, this enables durable tampering with local code and installed skill copies, potentially affecting future scheduled executions.
Security: Keep this file private. Never commit to git. Restrict permissions:
chmod 600 ~/.kalshi/key.pem
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
Set in shell profile or in launchd plist:
# ~/.zshrc or ~/.bash_profile
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Set in shell profile or in launchd plist:
# ~/.zshrc or ~/.bash_profile
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Set in shell profile or in launchd plist:
# ~/.zshrc or ~/.bash_profile
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Set in shell profile or in launchd plist:
# ~/.zshrc or ~/.bash_profile
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Set in shell profile or in launchd plist:
# ~/.zshrc or ~/.bash_profile
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Set in shell profile or in launchd plist:
# ~/.zshrc or ~/.bash_profile
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Set in shell profile or in launchd plist:
# ~/.zshrc or ~/.bash_profile
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Set in shell profile or in launchd plist:
# ~/.zshrc or ~/.bash_profile
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Set in shell profile or in launchd plist:
# ~/.zshrc or ~/.bash_profile
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
The state-file section documents automatic storage of detailed portfolio data on disk, including positions, shares, pricing, and P&L, but does not warn that this is sensitive financial information. If the file is left with permissive filesystem access, included in backups, synced to cloud storage, or read by other local users/processes, it can leak trading strategy and account exposure. The skill context increases sensitivity because the data reflects real portfolio holdings over time.
The troubleshooting guidance explicitly tells users to print credential material to the terminal with echo $KALSHI_KEY_ID and cat $KALSHI_KEY_PATH | head -1. While meant for debugging, this can expose secrets or key material to shell history, terminal logs, screen recordings, shared sessions, or support screenshots. In the context of a trading skill using live API credentials, that exposure can enable account misuse if mishandled.
# Create plist as shown in Method 3 above
# Install:
launchctl load ~/Library/LaunchAgents/com.portfolio-drift-monitor.plist
# Check status:
launchctl list | grep portfolio
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
private_key = f.read()
config_obj = Configuration(
host="https://api.elections.kalshi.com/trade-api/v2"
)
config_obj.api_key_id = self.key_id
config_obj.private_key_pem = private_keyData is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
No suspicious patterns detected.