Back to skill

Security audit

MyCampfire

Security checks for vulnerabilities and agentic risk

Overview

The skill is transparent about being an autonomous prediction-market agent, but it should be reviewed because it can automate betting and its onboarding example stores a generated wallet private key in plaintext.

Install only if you intentionally want a Campfire prediction-market agent that can use your API key to create predictions, claim rewards, and place bets. Before enabling live trading, require explicit user approval or strict spend caps, use an encrypted keystore or credential manager instead of wallet_private_key.hex, avoid broad trigger activation, and verify the package hashes/provenance against the publisher's current files.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
skill.md:232
Finding
Wallet Private Key Persisted in Plaintext## Vulnerability Details **File Location**: `skill.md`, lines 232-235 **Vulnerability Type**: Plaintext storage of sensitive cryptographic material **Risk Level**: High ### Vulnerable Code ```python private_key_file = os.path.join(secure_dir, "wallet_private_key.hex") with open(private_key_file, "w", encoding="utf-8") as f: f.write(private_key) os.chmod(private_key_file, 0o600) ``` ### Technical Analysis The recommended onboarding workflow writes the newly generated EVM wallet private key directly to `~/.campfire/secure/wallet_private_key.hex` as plaintext. Setting the file mode to `0600` limits access to the owning operating-system account, but it does not encrypt the key at rest. Any malicious process operating under that account, compromised backup system, exposed disk snapshot, forensic reader, or later permission error can recover the complete private key without needing an additional secret. This implementation also conflicts with the project's own security guidance in `wallet_guide.md`, which recommends encrypted storage such as `wallet.enc` and states that private keys and API keys should be encrypted. The local access needed to store a wallet credential is relevant to the declared registration function, but retaining an unencrypted private key exceeds the minimum necessary exposure. Registration only requires creating a signature; it does not require permanent plaintext persistence. ### Attack Path 1. A user follows the onboarding example in `skill.md`. 2. The workflow generates an EVM private key and writes it to `~/.campfire/secure/wallet_private_key.hex`. 3. An attacker obtains read access through malware running as the user, a compromised home-directory backup, a disk snapshot, forensic access, or an accidental permission change. 4. The attacker copies the plaintext private key. 5. The attacker imports the key into an EVM-compatible wallet or signing library. 6. The attacker can generate signatures as the registered wallet and authoriz ...[truncated 1045 chars]
Remediation
## Remediation Suggestions 1. Do not create a persistent plaintext private-key file. 2. Store the key in an operating-system credential manager, hardware-backed keystore, HSM, cloud KMS, or equivalent protected secret store. 3. If file-based storage is unavoidable, use a standard encrypted EVM keystore format with a strong user-supplied passphrase. Keep the passphrase outside the keystore file and outside source code, logs, command-line arguments, and environment dumps. 4. Generate and sign inside the protected storage boundary whenever supported, so application code never receives the raw private key. 5. If the wallet is needed only for registration, consider keeping it solely in memory, producing the registration signature, and discarding the key unless continued wallet ownership is an explicit requirement. 6. If temporary plaintext material is unavoidable: - Create it in a private directory with mode `0700`. - Create the file atomically with mode `0600`. - Exclude it from backups and synchronization services. - Remove it immediately after conversion to encrypted storage. - Avoid printing its path or contents in logs. 7. Update the example to use the same encrypted `wallet.enc` storage model required by `wallet_guide.md`. 8. Warn existing users to treat any wallet generated with the current example as potentially exposed, migrate relevant authority or assets to a new wallet, and securely remove residual plaintext copies and backups.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (16)

External Script Fetching

High
Category
Supply Chain
Content
- 保留 `curl` 用于下载,但仅下载静态文件,不执行远程脚本。
- 任一文件哈希不匹配即中止,不覆盖本地已存在版本。
- 禁止使用 `curl ... | sh`、`curl ... | bash`。

## 快速接入
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
- 保留 `curl` 用于下载,但仅下载静态文件,不执行远程脚本。
- 任一文件哈希不匹配即中止,不覆盖本地已存在版本。
- 禁止使用 `curl ... | sh`、`curl ... | bash`。

## 快速接入
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documentation states that registration returns an API key only once and advises saving it, but provides no guidance on secure storage, rotation, or avoiding disclosure. In an agent integration context, this is dangerous because the credential grants authenticated access to trading and account functions; insecure handling can lead to account takeover and unauthorized financial actions.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The documented trading, reward-claim, and position-management endpoints can trigger financially impactful or irreversible actions, yet the API reference presents them as routine operations without warnings, confirmation requirements, or safety constraints. For an autonomous prediction-market agent, this increases the likelihood of accidental trades, excessive order placement, or unintended reward claims caused by prompt errors, logic bugs, or key misuse.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This heartbeat guidance explicitly automates prediction publication and order placement, which can trigger account-impacting financial actions without any explicit user-consent checkpoint, safety confirmation, or prominent warning. In the context of a prediction-market skill, this is especially risky because a user or downstream agent could follow the runbook literally and place real bets on a recurring schedule, causing unintended losses or abusive automated trading behavior.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The file is written as a platform rules document entirely in Chinese and does not indicate that users may choose another language or that the Chinese-only presentation is required for a region-specific or compliance reason. Under the language/locale policy rule, forcing a specific language without opt-in can be a policy violation.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger list contains very generic phrases such as 'browse markets', 'make prediction', 'place bet', and 'claim rewards' that can overlap with ordinary user requests. In an agent skill that can authenticate with an API key, register via wallet signature, and execute betting actions, broad activation phrases increase the chance of unintended invocation and potentially unauthorized or surprising transactional behavior.

Session Persistence

Medium
Category
Rogue Agent
Content
REGISTER_BODY_FILE="$SECURE_DIR/register_body.json"

# 1) 生成钱包 + 注册签名,并将敏感信息写入本地安全文件
mkdir -p "$SECURE_DIR"
python - <<'PY'
from eth_account import Account
from eth_account.messages import encode_defunct
Confidence
95% confidence
Finding
The skill explicitly generates a new wallet private key and persists it to disk in a predictable local path, alongside registration artifacts. Even with restrictive file permissions, long-term plaintext storage of a blockchain private key materially increases the blast radius of local compromise, backups, malware, or accidental disclosure; anyone obtaining the key can fully control the associated wallet identity.

External Transmission

Medium
Category
Data Exfiltration
Content
PY

# 2) 注册(注意固定请求头必填)
curl -sS -X POST "$BASE_URL/agent-api/v1/register" \
  -H "tenant-id: 1" \
  -H "Content-Type: application/json" \
  -d @"$REGISTER_BODY_FILE"
Confidence
89% confidence
Finding
The registration command transmits sensitive onboarding material from a local file to a remote service. Although sending a signed registration payload to the platform is expected behavior for this skill, it still creates a real exfiltration boundary because the file contains wallet address, signature, and agent metadata, and the workflow later obtains an API key from the same service. In a wallet- and token-managing skill, any outbound transmission of credential-related material is security-relevant.

Session Persistence

Medium
Category
Rogue Agent
Content
Agent Name: {your_agent_name}
Wallet: {your_wallet_address}

This will create an AI Agent account linked to this wallet.
```

## 注册步骤
Confidence
60% confidence
Finding
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.

Session Persistence

Medium
Category
Rogue Agent
Content
Agent Name: {your_agent_name}
Wallet: {your_wallet_address}

This will create an AI Agent account linked to this wallet.
```

## 注册步骤
Confidence
60% confidence
Finding
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.

External Transmission

Medium
Category
Data Exfiltration
Content
private_key=private_key
).signature.hex()

resp = requests.post(
    f"{BASE_URL}/agent-api/v1/register",
    headers={
        "Content-Type": "application/json",
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
建议至少满足以下基线:

1. 私钥与 API Key 分开存储,且都要加密
2. 文件权限最小化(Linux 建议 `chmod 600`)
3. 不写入代码仓库、CI 日志、崩溃上报

推荐目录(示例):
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The file is entirely written in Chinese and does not indicate that language selection is optional or that the skill is intentionally limited to a Chinese-speaking or region-specific audience. Under the policy rule, forcing a specific language without user opt-in can be a locale-policy issue.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
SQP-3 applies to all file types and covers language or locale policy violations. This markdown file presents all operational guidance only in Chinese and does not mention that the language is optional, selectable, or limited to a justified region-specific audience.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The manifest description forces a specific language presentation in natural-language metadata, but it does not offer an alternative language or indicate that Chinese is optional. This may violate organizational language or locale expectations when users have not opted into that language.

Static analysis

No suspicious patterns detected.