Back to skill

Security audit

earn-hunter

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its OKX earn-monitoring purpose, but it creates persistent scheduled execution and has concrete implementation risks that could affect local commands, credentials, scheduled jobs, and live financial actions.

Install only if you are comfortable granting this skill access to your authenticated OKX CLI and allowing it to create recurring jobs. Before enabling background scheduling or purchase flows, require fixes for env.snapshot sourcing, safer crontab management, explicit confirmation for persistence and financial actions, safer Telegram token handling, and integrity-pinned dependency installation.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/scan.sh:37
Finding
Persistent Arbitrary Command Execution Through Sourced Environment Snapshot<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:57-65`; `scripts/scan.sh:37-40` **Vulnerability Type**: Executable configuration injection **Risk Level**: High ### Vulnerable Code ```bash # SKILL.md:57-65 cat > ~/.okx/earn-hunter/env.snapshot << SNAP # auto-generated by earn-hunter activation — $(date -Iseconds) OKX_BIN=$(command -v okx) NODE_BIN=$(command -v node) JQ_BIN=$(command -v jq) ACTIVATION_PATH=$PATH SNAP ``` ```bash # scripts/scan.sh:37-40 _EH_SNAPSHOT="${EH_STATE_DIR:-$HOME/.okx/earn-hunter}/env.snapshot" # shellcheck disable=SC1090 [[ -f "$_EH_SNAPSHOT" ]] && source "$_EH_SNAPSHOT" ``` ### Technical Analysis The activation procedure generates `env.snapshot` by interpolating executable paths and the current `PATH` without shell escaping. The scanner subsequently loads this file using `source`, which treats its contents as shell code rather than inert configuration data. If an executable path or `PATH` entry contains shell metacharacters, command substitution, or statement delimiters, those characters are written into the snapshot and interpreted when the scheduled scanner sources it. The problem is especially significant because the scanner can be registered in OS crontab or a macOS LaunchAgent, causing injected commands to execute repeatedly across sessions. The file also resides in a user-controlled state directory without an explicit ownership, regular-file, or restrictive-permission check before it is sourced. ### Attack Path 1. An attacker who can influence the activation environment places a maliciously named directory or executable earlier in `PATH`, or modifies `~/.okx/earn-hunter/env.snapshot` after activation. 2. `command -v` or `$PATH` produces text containing shell syntax, such as command substitution or an additional command. 3. Activation writes that text to `env.snapshot` without escaping it. 4. The Skill installs or invokes the recurring scanner. 5. `scan.sh` executes `source "$_EH_SNAPSHOT"`. 6. Bash parses t ...[truncated 553 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not use `source` to read generated configuration. 2. Store resolved paths in a non-executable format such as JSON: ```bash jq -n \ --arg okx "$(command -v okx)" \ --arg node "$(command -v node)" \ --arg jq_bin "$(command -v jq)" \ '{okx_bin:$okx,node_bin:$node,jq_bin:$jq_bin}' \ > ~/.okx/earn-hunter/env.snapshot.json chmod 600 ~/.okx/earn-hunter/env.snapshot.json ``` 3. Read individual values using the already resolved trusted `jq` binary, without evaluating their contents. 4. If shell assignments must be retained, serialize every value with `printf '%q'`; replacing `source` remains preferable. 5. Create `~/.okx/earn-hunter` with mode `0700` and snapshot/configuration files with mode `0600`. 6. Before reading the snapshot, verify that it is a regular file, is owned by the current user, is not a symbolic link, and is not writable by group or other users. 7. Validate resolved paths against an allowlist of expected absolute-path characters and verify the ownership and executable type of each selected binary. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/scan.sh:304
Finding
Telegram Bot Token Exposed in Curl Process Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/scan.sh:304-324` **Vulnerability Type**: Sensitive credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```bash local tg_token_env tg_chat_env tg_token_env=$(jq -r '.notify.telegram.bot_token_env // "TELEGRAM_BOT_TOKEN"' "$PLATFORM_FILE" 2>/dev/null) tg_chat_env=$(jq -r '.notify.telegram.chat_id_env // "TELEGRAM_CHAT_ID"' "$PLATFORM_FILE" 2>/dev/null) local TOKEN CHAT_ID TOKEN=$(printenv "$tg_token_env" 2>/dev/null) CHAT_ID=$(printenv "$tg_chat_env" 2>/dev/null) if [[ "${EH_DRY_RUN:-0}" == "1" ]]; then echo "=== [DRY-RUN TG] chat=$CHAT_ID ===" printf '%s\n' "$msg" log_notify "TG" "OK" "$detail (dry-run)" return 0 fi local resp resp=$(curl -s "https://api.telegram.org/bot${TOKEN}/sendMessage" \ --data-urlencode "chat_id=${CHAT_ID}" \ --data-urlencode "text=${msg}" \ -d "parse_mode=HTML" 2>/dev/null) ``` ### Technical Analysis Although the token is initially obtained from an environment variable, it is interpolated into the Telegram API URL passed directly to `curl`. Consequently, the bot token becomes part of curl's argument vector. Depending on operating-system process visibility, tracing configuration, endpoint-monitoring software, crash collection, or execution wrappers, command-line arguments may be observable while curl is running. The use of an environment variable therefore does not keep the secret out of process metadata. The Telegram Bot API treats the token as an authentication credential. Disclosure allows calls to the bot API without access to the original host. ### Attack Path 1. A scheduled scan finds an opportunity or generates an error notification. 2. `send_telegram` reads the bot token from the configured environment variable. 3. The script starts curl with the token embedded in the command-line URL. 4. A local process observer, diagnostic agent, tracing system, or command-execution logger records the curl argument vector. 5 ...[truncated 620 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Avoid placing the token in a command-line argument. 2. Pass sensitive curl configuration through standard input or a protected temporary file rather than through `argv`. 3. If a temporary configuration file is necessary: - Create it with `mktemp`. - Set mode `0600`. - Install an `EXIT` trap that securely removes it. - Ensure the token is never written to logs. 4. Run the scanner under a dedicated, minimally privileged account where practical. 5. Disable shell tracing around notification code and ensure process-monitoring systems redact Telegram bot URLs. 6. Rotate the Telegram bot token if process arguments may already have been collected. 7. Keep the chat ID and message body out of diagnostic logs unless the user explicitly enables verbose diagnostics. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:13
Finding
Automatic Installation of Executable Third-Party Dependencies Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:13-18`; `SKILL.md:28-45` **Vulnerability Type**: Unverified dependency and Skill installation **Risk Level**: Medium ### Vulnerable Code ```yaml install: - id: okx-cli kind: node package: "@okx_ai/okx-trade-cli@1.4.2" bins: ["okx"] label: "Install okx CLI (npm)" ``` ```bash # SKILL.md:28-45 which okx npm install -g @okx_ai/okx-trade-cli okx skill list --json okx skill add okx-cex-earn okx skill add okx-cex-auth ``` The instructions further state that missing optional Skills should be installed automatically: ```text If either is missing, attempt to install but do not block if installation fails. ``` ### Technical Analysis Activation can globally install executable npm content and can automatically add two additional Skills. Although the npm package is version-pinned, no package integrity hash, signature, lockfile, or verified artifact source is supplied. Global npm installation can also run package lifecycle scripts with the activating user's privileges. The two additional Skills are referenced without explicit version or integrity constraints. Their contents can therefore change independently of this audited artifact. Automatic installation extends the effective trusted codebase beyond the files reviewed in this project. This is a supply-chain exposure rather than proof that the named dependencies are malicious. The risk arises from automatically executing externally maintained components without binding installation to reviewed content. ### Attack Path 1. A user activates the Skill on a system where the OKX CLI or optional Skills are missing. 2. The activation instructions cause the agent to install the npm package globally and add marketplace Skills. 3. A registry account, package distribution channel, marketplace entry, or newly resolved dependency version is compromised. 4. Malicious lifecycle code or Skill instructions are delivered during installation. 5. The ex ...[truncated 783 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require explicit user approval before installing each external package or Skill. 2. Pin exact versions for all optional Skills and their transitive dependencies. 3. Verify cryptographic integrity using package hashes, signatures, provenance attestations, or a trusted lockfile. 4. Avoid global npm installation. Prefer a dedicated installation directory, isolated environment, or package manager mode that does not modify the user's global toolchain. 5. Disable npm lifecycle scripts where they are unnecessary, or review every required lifecycle script before execution. 6. Document the expected publisher, registry, package digest, and permissions of every dependency. 7. Treat optional purchase and authentication Skills as separate trust decisions; monitoring should remain functional without installing them. 8. Re-audit dependency artifacts whenever their pinned versions or hashes change. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:312
Finding
Crontab Installation and Removal Can Overwrite Unrelated Scheduled Jobs<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:312-327`, `SKILL.md:475-477`; `references/scheduler-setup.md:56-60`, `references/scheduler-setup.md:74-78` **Vulnerability Type**: Unsafe modification of user crontab **Risk Level**: Medium ### Vulnerable Code ```bash # SKILL.md:312-327 (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 - if [[ "$(uname -s)" == "Darwin" ]] && ! launchctl list com.vix.cron >/dev/null 2>&1; then # cron daemon not running — fallback to LaunchAgent fi ``` ```bash # SKILL.md:475-477 crontab -l | grep -v 'earn-hunter' | crontab - ``` The same unsafe management pattern is repeated in `references/scheduler-setup.md`: ```bash (crontab -l 2>/dev/null; echo "0 * * * * OKX_PROFILE=live ~/.okx/earn-hunter/scan.sh >> ~/.okx/earn-hunter/cron.log 2>&1") | crontab - ``` ```bash crontab -l | grep -v 'earn-hunter' | crontab - ``` ### Technical Analysis The installation pipeline suppresses errors from `crontab -l` and unconditionally pipes the combined output into `crontab -`. If listing the current crontab fails for a reason other than the user having no existing crontab, the pipeline may install only the new Earn Hunter line and discard existing entries. Repeated activation does not check for an existing managed entry, so duplicate jobs can be added. This can produce repeated scans, duplicate API traffic, and duplicate notifications. The pause command removes every line containing the substring `earn-hunter`. It does not use an exact command match or a uniquely delimited managed block. Unrelated jobs whose comments, paths, or commands contain that string can therefore be deleted. ### Attack Path #### Existing-job loss during installation 1. The user already has scheduled jobs. 2. `crontab -l` fails because of a temporary permission, service, storage, or command error. 3. The error is hidden by `2>/dev/null`. 4. The shell ...[truncated 874 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Capture the existing crontab separately and inspect the exit status before modifying it. 2. Distinguish the expected “no crontab for user” condition from actual failures; abort on every unexpected error. 3. Back up the current crontab before installation. 4. Use unique managed markers, for example: ```text # BEGIN earn-hunter managed job 0 * * * * ... # END earn-hunter managed job ``` 5. Replace or remove only the exact marked block. 6. Check for an existing entry before insertion so activation is idempotent. 7. Write the proposed new crontab to a temporary file, validate it, and install it only after successful construction. 8. After installation, list the crontab and verify that both the managed job and all pre-existing entries remain present. 9. On uninstall, remove only the exact command or managed block rather than filtering on a broad substring. ]]>
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 (78)

Ae1

High
Category
analysis-evasion
Content
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
ion/config management. The recurring **scan itself is performed entirely by `scripts/scan.sh`** (shell + jq) — `jq` is required for scanning. Verify with `which
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

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

High
Category
YARA Match
Content
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
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
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
Confidence
91% confidence
Finding
The uninstall flow includes a direct `rm -f ~/Library/LaunchAgents/com.okx.earn-hunter.plist` shell deletion command. Even though the path is fixed, destructive file operations in response to vague triggers like 'uninstall' are risky in agent contexts, and if similar patterns expand later they can become a vehicle for arbitrary or mistaken deletion.

Chaining Abuse

High
Category
Tool Misuse
Content
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
Confidence
90% confidence
Finding
Chaining `launchctl unload ... && rm -f ...` combines state-changing operations in one shell command, making partial failures harder to reason about and review. In an agent setting, command chaining increases the risk that a privileged action proceeds without granular validation or clear user visibility.

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

High
Category
YARA Match
Content
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
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The document claims earn-hunter does not directly perform write operations, but later includes direct transfer and redeem commands in its own flow. This contradiction can bypass user expectations and reviewer assumptions, making the skill more dangerous because a supposedly advisory skill is effectively authorized to move funds before final purchase steps complete.

Memory Manipulation

High
Category
Memory Poisoning
Content
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
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
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
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
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
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

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

High
Category
YARA Match
Content
# 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
Confidence
75% confidence
Finding
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill explicitly directs the agent to perform shell actions such as installing packages, copying scripts, editing files, invoking cron, and loading LaunchAgents, but it declares no explicit tool scope or permission boundary. That mismatch increases the chance the skill is granted broader execution capability than users expect, making destructive or persistent operations easier to trigger.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The activation trigger list includes broad natural-language phrases like 'monitor earn' and 'notify me about earn' that could match ordinary conversation and invoke a skill that installs software, writes files, and establishes recurring jobs. Because the skill performs persistent system changes, accidental invocation materially raises risk.

Session Persistence

Medium
Category
Rogue Agent
Content
- 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)
Confidence
82% confidence
Finding
Initializing `~/.okx/earn-hunter/` and writing config/state files creates durable state on disk. Disk persistence is expected here, but it is still security-relevant because it stores operational behavior and can support later automated execution when combined with the scheduler steps.

Vague Triggers

Medium
Confidence
97% confidence
Finding
The routing table maps very broad phrases like 'subscribe', 'stop', and 'uninstall' to privileged behaviors without sufficient contextual qualification. In a live trading and persistence-oriented skill, such generic triggers could cause unwanted financial workflow handoff, disable monitoring, or remove scheduled jobs and files based on ambiguous user input.

Session Persistence

Medium
Category
Rogue Agent
Content
### 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
Confidence
80% confidence
Finding
Writing `platform.json` is another form of persistent local state that controls later scheduling and notification behavior. In context it is less severe than cron installation, but it still contributes to durable automation configuration.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
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.
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.

Session Persistence

Medium
Category
Rogue Agent
Content
**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:
Confidence
98% confidence
Finding
The skill instructs the agent to install an OS crontab entry that runs hourly and persists beyond the current session. Persistent scheduled execution is security-sensitive because it enables continued command execution and external notifications even when the user is absent; in an agent-skill context this is exactly the kind of long-lived automation that requires strong consent and tight scoping.

Session Persistence

Medium
Category
Rogue Agent
Content
**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"
Confidence
97% confidence
Finding
Generating a LaunchAgent plist is a direct persistence mechanism on macOS. In a skill that can execute shell commands, this allows unattended recurring execution outside the original user interaction, which is inherently sensitive.

Static analysis

No suspicious patterns detected.