T01 · Skill Instruction Hijacking
- Location
SKILL.md:50- Finding
Forced Forwarding Bypasses Agent Review and User Confirmation
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill matches its HeySummon notification purpose, but it should be reviewed because it auto-forwards replies, starts a persistent watcher, and handles local tokens and plaintext logs with weak scoping.
Install only if you are comfortable with a background watcher that keeps running after setup, reads local HeySummon and OpenClaw credentials, sends notification and reply content through HeySummon, and stores raw event history locally. Use an HTTPS HeySummon URL for any non-local service, protect .env, avoid sending sensitive content through automatic replies, and run the teardown script when you no longer need the watcher.
SKILL.md:50Forced Forwarding Bypasses Agent Review and User Confirmation
scripts/setup.sh:31Watcher Is Persisted Across Shell and Agent Sessions
scripts/mercure-watcher.sh:207Provider Credentials and Plaintext Responses Can Be Transmitted over Unencrypted HTTP
scripts/mercure-watcher.sh:12Unbounded Plaintext Event Logging Uses Unspecified File Permissions
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Copy .env.example and fill in your values:
cp .env.example .env
| Variable | Required | Description |
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
## Setup
### Step 1: Configure .env
Check if `.env` exists in `{baseDir}`. If not, copy from `.env.example`:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
## Setup
### Step 1: Configure .env
Check if `.env` exists in `{baseDir}`. If not, copy from `.env.example`:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
## Setup
### Step 1: Configure .env
Check if `.env` exists in `{baseDir}`. If not, copy from `.env.example`:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
[ -f "$SKILL_DIR/.env" ] && set -a && source "$SKILL_DIR/.env" && set +a
BASE_URL="${HEYSUMMON_BASE_URL:-http://localhost:3456}"
API_KEY="${HEYSUMMON_API_KEY:?ERROR: Set HEYSUMMON_API_KEY}"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
[ -f "$SKILL_DIR/.env" ] && set -a && source "$SKILL_DIR/.env" && set +a
BASE_URL="${HEYSUMMON_BASE_URL:-http://localhost:3456}"
API_KEY="${HEYSUMMON_API_KEY:?ERROR: Set HEYSUMMON_API_KEY}"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
[ -f "$SKILL_DIR/.env" ] && set -a && source "$SKILL_DIR/.env" && set +a
BASE_URL="${HEYSUMMON_BASE_URL:-http://localhost:3456}"
API_KEY="${HEYSUMMON_API_KEY:?ERROR: Set HEYSUMMON_API_KEY}"
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
[ -f "$SKILL_DIR/.env" ] && set -a && source "$SKILL_DIR/.env" && set +a
BASE_URL="${HEYSUMMON_BASE_URL:-http://localhost:3456}"
API_KEY="${HEYSUMMON_API_KEY:?ERROR: Set HEYSUMMON_API_KEY}"
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
send_ack() {
local request_id="$1"
[[ -z "$request_id" ]] && return
curl -s -X POST "${ACK_URL}/${request_id}" \
-H "x-api-key: ${API_KEY}" \
>/dev/null 2>&1
}
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
args:{action:'send',message:process.argv[1],target:process.argv[2]}
}))" "$msg" "$NOTIFY_TARGET" 2>/dev/null)
curl -s "http://127.0.0.1:${OPENCLAW_PORT}/tools/invoke" \
-H "Authorization: Bearer ${OPENCLAW_TOKEN}" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
fi
# Look up request by refCode
REQUEST=$(curl -s "${BASE_URL}/api/v1/requests/by-ref/${REF_CODE}" \
-H "x-api-key: ${API_KEY}")
REQUEST_ID=$(echo "$REQUEST" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const j=JSON.parse(d);console.log(j.requestId||j.id||'')}catch(e){console.log('')}})" 2>/dev/null)
The script sources a local .env file directly into the shell with source, which executes any shell code present in that file rather than only reading key-value pairs. If an attacker can modify .env, they can achieve arbitrary command execution when the script runs and also influence secrets like the API endpoint and key.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
[ -f "$SKILL_DIR/.env" ] && set -a && source "$SKILL_DIR/.env" && set +a
REQUEST_ID="${1:-}"
RESPONSE_TEXT="${2:-}"
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
exit 1
fi
RESULT=$(curl -s -X POST "${BASE_URL}/api/v1/message/${REQUEST_ID}" \
-H "Content-Type: application/json" \
-H "x-api-key: ${API_KEY}" \
-d "$(node -e "console.log(JSON.stringify({plaintext:process.argv[1],from:'provider'}))" "$RESPONSE_TEXT" 2>/dev/null)")
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.
exit 1
fi
RESULT=$(curl -s -X POST "${BASE_URL}/api/v1/message/${REQUEST_ID}" \
-H "Content-Type: application/json" \
-H "x-api-key: ${API_KEY}" \
-d "$(node -e "console.log(JSON.stringify({plaintext:process.argv[1],from:'provider'}))" "$RESPONSE_TEXT" 2>/dev/null)")
The script sources a local .env file directly into the shell, which executes any shell syntax present in that file rather than merely parsing key/value pairs. If an attacker can modify .env, they can achieve arbitrary command execution when setup.sh runs, and the file also contains sensitive credentials that are exported to child processes.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
[ -f "$SKILL_DIR/.env" ] && set -a && source "$SKILL_DIR/.env" && set +a
WATCHER="$SCRIPT_DIR/mercure-watcher.sh"
NAME="heysummon-provider-watcher"
The instruction to 'always forward immediately' and use 'no confirmation' delegates an external action to the system without a human verification step. Even though the action is simple, it can cause unintended disclosure, misdelivery, or abuse if a reply is parsed incorrectly or contains sensitive information.
## Reply-to-Respond
When the user replies to a 🦞 notification, parse the refCode (HS-XXXX) from the quoted message and use `reply-handler.sh`. **Always forward immediately — no AI processing, no confirmation.**
## Statuses
The skill explicitly instructs immediate forwarding of user replies to an external platform without warning or confirmation. This creates a real privacy and data-handling risk because users may unknowingly send sensitive content, quoted context, or secrets off-platform with no opportunity to review or cancel.
The script reads a bearer token from an unrelated local OpenClaw config file and uses it to invoke a local messaging gateway. This creates cross-component credential reuse and expands the trust boundary: any compromise or misuse of this watcher lets it act with the OpenClaw gateway's privileges, even though that token is not scoped to this skill.
The script logs the first 15 characters of the API key at startup. Partial secret disclosure materially aids secret identification, correlation across logs, and brute-force or matching attacks, especially when logs are centrally collected or visible to other local users.
The watcher forwards externally sourced event content into a privileged local tool invocation endpoint. Even though the destination is localhost, this is still a trust-boundary crossing that can leak sensitive event data to another subsystem and trigger downstream actions based on untrusted input.
args:{action:'send',message:process.argv[1],target:process.argv[2]}
}))" "$msg" "$NOTIFY_TARGET" 2>/dev/null)
curl -s "http://127.0.0.1:${OPENCLAW_PORT}/tools/invoke" \
-H "Authorization: Bearer ${OPENCLAW_TOKEN}" \
-H "Content-Type: application/json" \
-d "$PAYLOAD" \
The comment at L06 states that all encryption/security is handled by the platform, implying the script has no security-sensitive handling. In reality, the script loads a sensitive API key from .env at L12-L15 and constructs/sends plaintext message content over HTTP requests at L32-L46, so the documentation understates the script's direct security-relevant behavior.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
exit 1
fi
RESULT=$(curl -s -X POST "${BASE_URL}/api/v1/message/${REQUEST_ID}" \
-H "Content-Type: application/json" \
-H "x-api-key: ${API_KEY}" \
-d "$(node -e "console.log(JSON.stringify({plaintext:process.argv[1],from:'provider'}))" "$RESPONSE_TEXT" 2>/dev/null)")
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
exit 1
fi
RESULT=$(curl -s -X POST "${BASE_URL}/api/v1/message/${REQUEST_ID}" \
-H "Content-Type: application/json" \
-H "x-api-key: ${API_KEY}" \
-d "$(node -e "console.log(JSON.stringify({plaintext:process.argv[1],from:'provider'}))" "$RESPONSE_TEXT" 2>/dev/null)")
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.
kill "$(cat "$PIDFILE")" 2>/dev/null
fi
nohup bash "$WATCHER" >> "$LOGFILE" 2>&1 &
echo $! > "$PIDFILE"
echo "✅ Watcher started via nohup (PID: $(cat "$PIDFILE"), log: $LOGFILE)"
fi
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.
kill "$(cat "$PIDFILE")" 2>/dev/null
fi
nohup bash "$WATCHER" >> "$LOGFILE" 2>&1 &
echo $! > "$PIDFILE"
echo "✅ Watcher started via nohup (PID: $(cat "$PIDFILE"), log: $LOGFILE)"
fi
No suspicious patterns detected.