Back to skill

Security audit

Earn Hunter

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its OKX Earn monitoring purpose, but it combines financial account access, recurring background execution, credential-handling risks, and an undisclosed hard-coded OKX link that users should review before installing.

Install only if you are comfortable with a skill that uses your OKX CLI authentication, stores local monitoring state, sends financial opportunity notifications to Telegram/Lark or chat, and can create recurring background jobs. Before enabling it, prefer pinned installs, avoid exposing OKX API-key config output, review the hard-coded OKX link, and confirm exactly which scheduler and notification channel will be used.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
Findings (6)

T01 · Skill Instruction Hijacking

Warning
Location
scripts/scan.sh:170
Finding

Hard-Coded Promotional URL Injected into Recurring Notifications

Content
View full analysis
Remediation
View remediation

T06 · System Persistence

Warning
Location
SKILL.md:272
Finding

Recurring Cross-Session Execution Is Installed Without a Dedicated Persistence Confirmation

Content
View full analysis
/dev/null; echo "0 * * * * PATH=$CRON_PATH OKX_PROFILE=live ~/.okx/earn-hunter/scan.sh >> ~/.okx/earn-hunter/cron.log 2>&1") | crontab - ``` macOS LaunchAgent installation: ```bash launchctl load ~/Library/LaunchAgents/com.okx.earn-hunter.plist ``` The generated LaunchAgent includes: ```xml RunAtLoad ``` OpenClaw installation creates a recurring isolated agent turn with the following significant fields: ```json { "name": "earn-hunter-hourly", "sessionTarget": "isolated", "payload": { "kind": "agentTurn", "message": "Execute the earn-hunter scan", "lightContext": true }, "delivery": { "mode": "announce" } } ``` ### Technical Analysis Periodic execution is relevant to the declared monitoring function. However, the activation instructions proceed from general setup into scheduler creation without requiring a separate, explicit confirmation immediately before installing persistence. The OS variants survive the original Skill session. The LaunchAgent also survives login or restart and executes immediately because `RunAtLoad` is enabled. The OpenClaw variant creates repeated agent sessions whose available tools are determined by the broader agent configuration rather than a per-job allowlist. The OpenClaw documentation explicitly acknowledges that `lightContext` does not restrict which tools are loaded. Consequently, recurring agent turns may receive more capabilities than are necessary to execute the local scan script. ### Attack Path 1. The user starts the general activation flow. 2. The Skill copies an executable scanner into `~/.okx/earn-hunter/`. 3. Depending on the detected platform, it registers an OS crontab entry, loads a LaunchAgent, ...[truncated 930 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/scan.sh:37
Finding

Writable State File Is Executed as Shell Code by Every Scheduled Scan

Content
View full analysis
~/.okx/earn-hunter/env.snapshot << SNAP # auto-generated by earn-hunter activation OKX_BIN=$(command -v okx) NODE_BIN=$(command -v node) JQ_BIN=$(command -v jq) ACTIVATION_PATH=$PATH SNAP ``` The recurring scanner executes the file: ```bash _EH_SNAPSHOT="${EH_STATE_DIR:-$HOME/.okx/earn-hunter}/env.snapshot" # shellcheck disable=SC1090 [[ -f "$_EH_SNAPSHOT" ]] && source "$_EH_SNAPSHOT" ``` ### Technical Analysis `source` does not parse a data format; it evaluates the target file as arbitrary shell code in the current process. The snapshot is stored alongside ordinary writable configuration and state files, but it is implicitly trusted as executable code on every scan. The generated path values are also inserted without robust shell escaping. A path containing shell metacharacters, whitespace, command substitution syntax, or line breaks can alter the generated file's semantics. More importantly, any local process able to modify `env.snapshot` can insert arbitrary shell commands. The risk is amplified by the configured persistence mechanisms: injected commands execute repeatedly under cron or LaunchAgent without further user interaction. ### Attack Path 1. An attacker or compromised local process obtains write access to `~/.okx/earn-hunter/env.snapshot` or its containing directory. 2. The attacker appends a shell command to the snapshot. 3. The hourly cron job or LaunchAgent starts `scan.sh`. 4. `scan.sh` invokes `source "$_EH_SNAPSHOT"`. 5. The injected command executes with the privileges and environment of the user running the scheduler. 6. The command can repeat on every scheduled invocation until the snapshot or scheduler is removed. ### Impact Assessment Successful ...[truncated 312 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:47
Finding

Authentication Detection Can Expose the API Key to Agent Context and Logs

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:13
Finding

Activation Installs Unpinned Executable Dependencies and Optional Skills

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:312
Finding

Crontab Management Is Non-Idempotent and Can Delete Unrelated Jobs

Content
View full analysis
/dev/null; echo "0 * * * * PATH=$CRON_PATH OKX_PROFILE=live ~/.okx/earn-hunter/scan.sh >> ~/.okx/earn-hunter/cron.log 2>&1") | crontab - ``` The pause command removes every line containing the generic text `earn-hunter`: ```bash crontab -l | grep -v 'earn-hunter' | crontab - ``` ### Technical Analysis Repeated activation appends duplicate entries because installation is not idempotent. Each duplicate independently runs the scanner, potentially causing overlapping state writes and repeated network requests. Pause and uninstall rewrite the user's complete crontab after filtering lines with an imprecise substring. Any unrelated job, comment, environment declaration, or command containing `earn-hunter` will also be removed. The pipeline also lacks robust failure handling. If listing or filtering the crontab fails unexpectedly, piping incomplete content into `crontab -` can replace the existing schedule with unintended data. ### Attack Path **Duplicate execution path:** 1. The user runs activation more than once. 2. Each activation appends another identical entry. 3. Multiple scans start at the same scheduled time. 4. Concurrent processes read and overwrite the same state file. 5. Duplicate alerts, excess API traffic, or state corruption may occur. **Unrelated-job deletion path:** 1. The user has another crontab line containing the substring `earn-hunter`. 2. The user asks the Skill to pause or uninstall its monitor. 3. The Skill runs `grep -v 'earn-hunter'`. 4. Every matching line is removed. 5. The filtered content replaces the entire user crontab. ### Impact Assessment The issue can disrupt unrelated scheduled task ...[truncated 247 chars]
Remediation
View remediation
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (83)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

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

md
b, no CLI commands). The job runs as an **isolated, light-context** agent turn and delivers its output back to the conversation channel via cron **`announce`** delivery. notify.channel defaults to `"session"` so the scan prints to stdout for `announce` to push (avoids double-send).

**Claude Code / Hermes / Generic (`claude-code.default.json`):**
- scheduler.type = `"cron"` — scheduled via **OS crontab → `scripts/scan.sh`** (zero LLM token cost), notification via TG / Lark curl from the script itself.

### Notification Channels (independent of platform)

Detect in priority order (PRD requirement: TG first):
1. **Telegram** — `$TELEGRAM_BOT_TOKEN` and `$TELEGRAM_CHAT_ID` both set → TG ready
2. **Lark** — `platform.notify.lark_webhook` non-empty → Lark ready
3. **Session** — fallback, only works in interactive mode

TG and Lark are **standalone push channels** — they work regardless of whether the agent client is open. On OS-crontab platforms, scheduled scans send notific

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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).

Content

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

md
When user says "卸载" / "uninstall":
1. Stop the scheduler (same as Pause). For LaunchAgent, also remove the plist:
   `launchctl unload ~/Library/LaunchAgents/com.okx.earn-hunter.plist && rm -f ~/Library/LaunchAgents/com.okx.earn-hunter.plist`
2. Ask: "是否保留配置和历史数据?"
   - Yes → only remove scheduler
   - No → also remove `~/.okx/earn-hunter/` directory

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

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

md
When user says "卸载" / "uninstall":
1. Stop the scheduler (same as Pause). For LaunchAgent, also remove the plist:
   `launchctl unload ~/Library/LaunchAgents/com.okx.earn-hunter.plist && rm -f ~/Library/LaunchAgents/com.okx.earn-hunter.plist`
2. Ask: "是否保留配置和历史数据?"
   - Yes → only remove scheduler
   - No → also remove `~/.okx/earn-hunter/` directory

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · references/notify-channels.md (reported line 13)May include surrounding context.

md
ding which applies avoids confusion.

### 1. Interactive Session (user is in a live conversation)

The agent outputs markdown directly in the conversation. Works on all platforms (OpenClaw, Claude Code, Hermes, Generic). Full interactivity — user can reply to subscribe immediately.

### 2. OS Crontab (scheduled scan, no LLM session) — Claude Code / Hermes / Generic

Scheduled scans run via OS crontab (no LLM session). **Always use direct curl to TG Bot API or Lark Webhook** for notifications. `scripts/scan.sh` does the curl itself.

### 3. OpenClaw In-Session Cron (`announce` delivery)

On OpenClaw the scheduled scan runs as an **isolated cron agent turn** created via the in-session `cron` tool. Delivery is via the cron job's **`announce`** mode, which pushes the turn's output back to the conversation channel that created the job. `platform.json` `notify.channel` is `"session"` so `scripts/scan.sh` prints the notification to stdout for the turn to relay — **do not curl TG/Lark fr

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · references/scan-logic.md (reported line 280)May include surrounding context.

md
current_flash_ids = [p.id for each in flash_results]
   For each key in state.flash:
     Extract id from key (split by ":" → first element)
     If id not in current_flash_ids → delete state.flash[key]
   Skip any key starting with "test:" (Test Mode immunity)

   # 6b. Fixed diff cleanup: key-level

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · references/scan-logic.md (reported line 287)May include surrounding context.

md
current_flash_ids = [p.id for each in flash_results]
   For each key in state.flash:
     Extract id from key (split by ":" → first element)
     If id not in current_flash_ids → delete state.flash[key]
   Skip any key starting with "test:" (Test Mode immunity)

   # 6b. Fixed diff cleanup: key-level

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · references/scan-logic.md (reported line 295)May include surrounding context.

md
current_flash_ids = [p.id for each in flash_results]
   For each key in state.flash:
     Extract id from key (split by ":" → first element)
     If id not in current_flash_ids → delete state.flash[key]
   Skip any key starting with "test:" (Test Mode immunity)

   # 6b. Fixed diff cleanup: key-level

YARA rule 'backdoor_persistence': Backdoor persistence with malicious payloads (shell commands, SSH key injection, hidden root users) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · references/scheduler-setup.md (reported line 6)May include surrounding context.

md
# Scheduler Setup

Two scheduling models, selected by `platform.json` `.scheduler.type`:

- **`openclaw-cron`** (OpenClaw) — scheduled via the in-session **`cron` agent tool**, isolated + light-context, delivered back to the conversation via `announce`. See [OpenClaw](#openclaw-in-session-cron-tool).
- **`cron`** (Claude Code / Hermes / Generic) — scheduled via **OS crontab + `okx` CLI + curl notifications**. No LLM sessions spawned — zero token cost. See [OS Crontab](#os-crontab-configuration).

For OS-crontab platforms, agent-platform `/loop` and cloud Routines are **not recommended**: each tick spawns an LLM session and isolated sessions cannot reliably push TG/Lark notifications. (OpenClaw is the deliberate exception — its in-session cron + `announce` delivery is the supported path.)

## OpenClaw (in-session cron tool)

OpenClaw does **not** use OS crontab or the `openclaw` CLI (the CLI cron path has permission issues here). Scheduling is created

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill explicitly instructs the agent to execute numerous shell commands, install packages, edit files under the user's home directory, and register scheduled jobs, yet it declares no tool scope or allowed-tools restrictions. That mismatch weakens least-privilege controls and increases the blast radius if the skill is invoked unexpectedly or if later content changes introduce more dangerous commands.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list contains broad phrases such as 'monitor earn', 'notify me about earn', and similar natural-language variants that can match ordinary conversation without clear intent to activate a powerful automation skill. Because activation can lead to installs, auth checks, config writes, and scheduler setup, accidental routing materially increases risk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
89% confidence
Finding

The skill persists configuration, state, platform metadata, scripts, and environment snapshots under ~/.okx/earn-hunter. Persistent writes are necessary for the feature, but they create long-lived local state that can later influence unattended execution and may expose operational details such as resolved binary paths.

Content

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

md
- No API key + `okx auth status --json` → `"status":"logged_in"` → **OAuth mode**. No `--profile` flag needed.
   - Neither → **stop**. Load `okx-cex-auth` skill and follow login steps.
5. Init config and state:
   - If `~/.okx/earn-hunter/` directory does not exist → `mkdir -p ~/.okx/earn-hunter`
   - If `~/.okx/earn-hunter/config.json` does not exist → copy `{baseDir}/config/default.json` to it
   - If `~/.okx/earn-hunter/state.json` does not exist → write `{"flash":{},"fixed":{},"flexible":{},"consecutive_failures":0,"last_error":""}`
   - If `~/.okx/earn-hunter/platform.json` does not exist → run [Platform Detection](#platform-detection-active-probe--user-confirmation)

Session Persistence

Medium
Category
Rogue Agent
Confidence
83% confidence
Finding

Writing platform.json establishes durable behavior for later runs, including scheduler and notification configuration. In isolation this is low risk, but in this skill it contributes to a larger persistent automation chain that can later drive unattended scans and outbound messaging.

Content

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

md
### Step 1 — Platform Detection & Confirmation

See [Platform Detection](#platform-detection-active-probe--user-confirmation). Probe environment → ask user to confirm → write `platform.json`.

### Step 2 — Detect Notification Channel & Confirm

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
5. User confirms → proceed to Step 5
6. Not received → troubleshoot (see `notify-channels.md`)
7. 5 min no response → ping once
8. Session channel → skip confirmation

**Note:** The smoke test ignores `verboseLog` setting — it always produces output to verify the full pipeline works end-to-end.

Session Persistence

Medium
Category
Rogue Agent
Confidence
97% confidence
Finding

The skill directs the agent to install a recurring crontab entry that executes a local script hourly and writes logs, creating durable automated execution outside the immediate chat session. Persistence is expected for a monitoring skill, but it is still security-sensitive because it can continue running, accessing auth context, and sending outbound notifications after the user disengages.

Content

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

Step A: Try crontab + verify cron daemon (macOS)

bash
(crontab -l 2>/dev/null; echo "0 * * * * PATH=$CRON_PATH OKX_PROFILE=live ~/.okx/earn-hunter/scan.sh >> ~/.okx/earn-hunter/cron.log 2>&1") | crontab -

On macOS (uname -s == Darwin), immediately check if the cron daemon is running:

Session Persistence

Medium
Category
Rogue Agent
Confidence
94% confidence
Finding

Generating a LaunchAgent plist is a concrete persistence mechanism that causes future execution of the scan script independent of user presence. In security analysis, background agents are inherently sensitive because they combine file persistence, recurring execution, and access to the user's existing auth/session context.

Content

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

Step B: macOS LaunchAgent fallback (scheduler.type = "launchagent")

Generate ~/Library/LaunchAgents/com.okx.earn-hunter.plist with the resolved paths:

bash
SCAN_SCRIPT="$HOME/.okx/earn-hunter/scan.sh"

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

This line is part of the here-doc that writes the LaunchAgent plist, which implements durable background execution. Even though the use case is legitimate monitoring, the persistence mechanism materially increases risk if the skill is mis-invoked or later altered.

Content

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

md
LOG_FILE="$HOME/.okx/earn-hunter/cron.log"
INTERVAL=3600  # derive from scheduler.interval: "1h"→3600, "30m"→1800, "10m"→600

cat > ~/Library/LaunchAgents/com.okx.earn-hunter.plist << PLIST
<?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">

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

This line is part of the here-doc that writes the LaunchAgent plist, which implements durable background execution. Even though the use case is legitimate monitoring, the persistence mechanism materially increases risk if the skill is mis-invoked or later altered.

Content

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

md
LOG_FILE="$HOME/.okx/earn-hunter/cron.log"
INTERVAL=3600  # derive from scheduler.interval: "1h"→3600, "30m"→1800, "10m"→600

cat > ~/Library/LaunchAgents/com.okx.earn-hunter.plist << PLIST
<?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">

Static analysis

No suspicious patterns detected.