Back to skill

Security audit

Hey summon

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its human-help purpose, but it needs review because it can keep running in the background, use a local OpenClaw token, and accidentally publish local secrets through Git auto-sync.

Review before installing. Use only with a trusted HeySummon endpoint, prefer HTTPS for any non-local server, avoid sending secrets or sensitive conversation context, do not run auto-sync.sh until a restrictive .gitignore and staging allowlist are added, and treat .env, providers.json, .keys, .requests, watcher logs, and the OpenClaw gateway token as sensitive credentials.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (6)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/auto-sync.sh:10
Finding
Automatic Git synchronization can upload API keys, private keys, and request data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/auto-sync.sh:10-19` **Vulnerability Type**: Indiscriminate staging and remote upload of sensitive files **Risk Level**: Critical ### Vulnerable Code ```bash git add -A if git diff --cached --quiet; then # No changes exit 0 fi # Commit and push changes TIMESTAMP=$(date -u +"%Y-%m-%d %H:%M:%S UTC") git commit -m "Auto-sync: $TIMESTAMP" --quiet git push origin main --quiet ``` ### Technical Analysis The synchronization script stages every changed or untracked file under the repository through `git add -A`, commits those files, and pushes them to the configured `origin` remote. This project stores sensitive material inside the project directory, including: - `.env`, which may contain the HeySummon API key and notification target. - `providers.json`, which stores provider API keys. - `.keys/`, which contains signing and encryption private keys. - `.requests/`, which contains active request identifiers and provider metadata. - Watcher logs and event records that may contain conversation content. The repository snapshot contains no `.gitignore`, although `README.md` states that these paths are already ignored. Consequently, the documented auto-sync behavior does not have the protection claimed by the documentation. ### Attack Path 1. A user configures the Skill and creates `.env`, `providers.json`, `.keys/`, or `.requests/`. 2. The user runs or schedules `scripts/auto-sync.sh` as documented. 3. `git add -A` stages all sensitive and non-sensitive files without an allowlist. 4. The script commits the staged files. 5. `git push origin main` uploads them to the configured Git remote. 6. Anyone with access to that remote can retrieve API credentials, private keys, request metadata, or logs. An attacker who controls or can modify the `origin` remote gains a direct exfiltration channel when the synchronization script runs. ### Impact Assessment Successful exploitation can disclose HeySummon API ke ...[truncated 449 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Add a restrictive `.gitignore` that excludes at minimum: - `.env` - `providers.json` - `.keys/` - `.requests/` - `.seen-events.txt` - `*.jsonl` - `scripts/watcher.log` - `scripts/watcher.pid` 2. Replace `git add -A` with an explicit allowlist of documentation and source files intended for publication. 3. Before committing, inspect `git diff --cached --name-only` and abort if any sensitive path is staged. 4. Add automated secret scanning before every push. 5. Do not enable scheduled synchronization by default; require explicit informed consent. 6. Rotate any API keys and cryptographic keys that may already have been pushed, and remove exposed data from the complete Git history. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/submit-request.sh:101
Finding
Questions and conversation context are transmitted without the claimed end-to-end encryption<![CDATA[ ## Vulnerability Details **File Location**: `scripts/submit-request.sh:101-110` **Vulnerability Type**: Plaintext transmission of potentially sensitive user content **Risk Level**: High ### Vulnerable Code ```bash RESPONSE=$(curl -s -X POST "${BASE_URL}/api/v1/help" \ -H "Content-Type: application/json" \ -d "$(node -e "console.log(JSON.stringify({ apiKey: process.argv[1], signPublicKey: process.argv[2], encryptPublicKey: process.argv[3], question: process.argv[4], messages: JSON.parse(process.argv[5]) }))" "$API_KEY" "$SIGN_PUB" "$ENC_PUB" "$QUESTION" "$MESSAGES")") ``` ### Technical Analysis The request body contains the API key, question, and complete `messages` context as directly readable JSON. Although public signing and encryption keys are included, the script does not invoke `crypto.mjs encrypt` before sending the question or messages. This conflicts with the claims in `README.md` and `SKILL.md` that the communication channel is end-to-end encrypted. Server-side encryption is not end-to-end encryption because the platform receives the plaintext and is therefore inside the trust boundary. The risk is heightened by the default `http://localhost:3445` URL and the ability to configure arbitrary non-TLS servers. ### Attack Path 1. A user relies on the documented end-to-end encryption claim. 2. The user submits a question containing source code, credentials, personal data, or private conversation history. 3. `submit-request.sh` inserts the question and messages directly into a JSON request body. 4. The configured HeySummon server receives and processes the plaintext. 5. If non-loopback HTTP is configured, a network-positioned attacker can also observe or modify the plaintext traffic. ### Impact Assessment The HeySummon platform can read all submitted questions and conversation context. On unencrypted network connections, passive or active network attackers can obtain the same information. The affected scope is all ...[truncated 149 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Encrypt the question and message context locally using the intended recipient's authenticated public encryption key before transmission. 2. Sign all relevant authenticated fields, including the ciphertext, request identifier, sender identity, and encryption metadata. 3. Ensure that the platform only relays ciphertext and cannot derive the content-encryption key. 4. Require authenticated HTTPS independently of application-layer encryption. 5. Correct the documentation to accurately describe the actual trust model until true client-side end-to-end encryption is implemented. 6. Ask for explicit user consent before transmitting conversation context and minimize the context to only what is required for the help request. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/add-provider.sh:12
Finding
API credentials can be sent to arbitrary or unencrypted endpoints<![CDATA[ ## Vulnerability Details **File Location**: `scripts/add-provider.sh:12-38` **Vulnerability Type**: Credential transmission without transport or destination validation **Risk Level**: High ### Vulnerable Code ```bash BASE_URL="${HEYSUMMON_BASE_URL:-http://localhost:3445}" PROVIDERS_FILE="${HEYSUMMON_PROVIDERS_FILE:-$SKILL_DIR/providers.json}" API_KEY="$1" ALIAS="$2" if [ -z "$API_KEY" ]; then echo "Usage: add-provider.sh <api-key> [alias]" >&2 echo "" >&2 echo " api-key Client key (hs_cli_... or htl_...) linked to the provider" >&2 echo " alias Optional friendly name (default: provider name from platform)" >&2 exit 1 fi # Validate key prefix if [[ "$API_KEY" =~ ^htl_prov_ ]] || [[ "$API_KEY" =~ ^hs_prov_ ]]; then echo "❌ This is a provider key. You need a CLIENT key (hs_cli_... or htl_...)." >&2 exit 1 fi if [[ ! "$API_KEY" =~ ^hs_cli_ ]] && [[ ! "$API_KEY" =~ ^htl_ ]]; then echo "❌ Invalid key format. Must start with 'hs_cli_' or 'htl_'." >&2 exit 1 fi # Fetch provider info RESPONSE=$(curl -s "${BASE_URL}/api/v1/whoami" -H "x-api-key: ${API_KEY}") ``` Related credential-bearing requests also occur in: - `scripts/platform-watcher.sh:88`, where the API key authenticates the SSE connection. - `scripts/platform-watcher.sh:157-158`, where it authenticates message retrieval. - `scripts/submit-request.sh:101-110`, where the API key is included in the request body. - `scripts/submit-request.sh:135`, where it is sent in an HTTP header. ### Technical Analysis `HEYSUMMON_BASE_URL` is accepted without validating the scheme, hostname, certificate policy, or approved destination. The API key is subsequently transmitted to that endpoint. HTTP is safe from network interception only when it remains on a trusted loopback interface. The scripts do not enforce that restriction. A malicious `.env`, inherited environment variable, or configuration instruction can redirect credentials to an attacker-controlled server. Prefix validation ...[truncated 1096 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require `https://` for every non-loopback endpoint. 2. Permit plaintext HTTP only when the parsed hostname is exactly a loopback address such as `127.0.0.1`, `::1`, or an appropriately validated local socket. 3. Maintain an explicit allowlist of trusted production service origins. 4. Reject URLs containing unexpected user information, fragments, redirects, or unsupported schemes. 5. Configure `curl` to fail securely with `--fail-with-body --proto '=https' --tlsv1.2` for remote connections. 6. Avoid putting API keys in JSON request bodies; use an authenticated header over TLS. 7. Use narrowly scoped and revocable tokens, and rotate credentials after suspected redirection or interception. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/platform-watcher.sh:23
Finding
Persistent watcher reads a high-value OpenClaw gateway token and invokes privileged local APIs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/platform-watcher.sh:23-60` **Vulnerability Type**: Excessive local privilege combined with persistent execution **Risk Level**: High ### Vulnerable Code ```bash # Read OpenClaw gateway token OPENCLAW_TOKEN=$(node -e "try{const p=require('path').join(require('os').homedir(),'.openclaw/openclaw.json');console.log(JSON.parse(require('fs').readFileSync(p,'utf8')).gateway.auth.token)}catch(e){}" 2>/dev/null) if [ -z "$OPENCLAW_TOKEN" ]; then echo "ERROR: Could not read OpenClaw gateway token" >&2 exit 1 fi mkdir -p "$REQUESTS_DIR" # Deduplication SEEN_FILE="$SKILL_DIR/.seen-events.txt" touch "$SEEN_FILE" tail -500 "$SEEN_FILE" > "${SEEN_FILE}.tmp" 2>/dev/null && mv "${SEEN_FILE}.tmp" "$SEEN_FILE" send_notification() { local MSG="$1" if [ "$NOTIFY_MODE" = "file" ]; then local EVENTS_FILE="${HEYSUMMON_EVENTS_FILE:-$HOME/.heysummon/consumer-events.jsonl}" mkdir -p "$(dirname "$EVENTS_FILE")" local TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") echo "{\"timestamp\":\"$TIMESTAMP\",\"message\":$(node -e "console.log(JSON.stringify(process.argv[1]))" "$MSG" 2>/dev/null)}" >> "$EVENTS_FILE" curl -s -X POST "http://127.0.0.1:${OPENCLAW_PORT}/cron/wake" \ -H "Authorization: Bearer ${OPENCLAW_TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"text\":\"$MSG\",\"mode\":\"now\",\"agentId\":\"secondary\"}" \ >/dev/null 2>&1 else local PAYLOAD PAYLOAD=$(node -e "console.log(JSON.stringify({ tool:'message', 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" \ >/dev/null 2>&1 fi } ``` The process is persisted by `scripts/setup.sh:36-40`: ```bash if command -v pm2 &>/dev/null; then pm2 delete "$ ...[truncated 2178 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a dedicated, revocable token limited to sending notifications to one configured target. 2. Do not read the primary OpenClaw gateway configuration directly from the user's home directory. 3. Use an operating-system credential store or restricted secret descriptor rather than retaining a broad token in a general-purpose shell process. 4. Make persistent PM2 registration an explicit opt-in and clearly disclose its lifecycle. 5. Avoid `pm2 save` by default, or provide a session-scoped watcher that terminates when no requests remain. 6. Validate event schemas and strictly bound message size before forwarding content. 7. Label provider responses as untrusted external data so downstream agents do not execute embedded instructions. 8. Restrict the gateway listener to loopback and enforce endpoint-specific authorization. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/crypto.mjs:23
Finding
Cryptographic private keys are created without explicit restrictive permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/crypto.mjs:23-43` **Vulnerability Type**: Insecure private-key file permissions **Risk Level**: Medium ### Vulnerable Code ```javascript if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } console.error(`🔑 Generating keypairs in ${dir}...`); // Ed25519 (signing) const ed = crypto.generateKeyPairSync('ed25519', { publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); fs.writeFileSync(path.join(dir, 'sign_public.pem'), ed.publicKey); fs.writeFileSync(path.join(dir, 'sign_private.pem'), ed.privateKey); // X25519 (encryption via DH) const x = crypto.generateKeyPairSync('x25519', { publicKeyEncoding: { type: 'spki', format: 'pem' }, privateKeyEncoding: { type: 'pkcs8', format: 'pem' } }); fs.writeFileSync(path.join(dir, 'encrypt_public.pem'), x.publicKey); fs.writeFileSync(path.join(dir, 'encrypt_private.pem'), x.privateKey); ``` ### Technical Analysis The key directory is created without an explicit `0700` mode, and private-key files are written without an explicit `0600` mode. Their effective permissions therefore depend on the process umask and any permissions already present on the directory. On systems with permissive umasks or shared group access, another local account may be able to read the signing and X25519 private keys. The documentation recommends manually applying restrictive permissions, but the code does not enforce them. ### Attack Path 1. The user runs setup or submits a request without existing keys. 2. `crypto.mjs keygen` creates the key directory and private-key files under the caller's current umask. 3. A permissive umask results in group-readable or world-readable material, or an existing permissive directory exposes the files. 4. Another local user reads `sign_private.pem` or `encrypt_private.pem`. 5. The attacker uses the stolen key material to impersonate the client or attempt to decrypt tr ...[truncated 517 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the key directory with mode `0700`. 2. Write private keys with mode `0600` and public keys with an intentional mode such as `0644`. 3. Apply `chmod` after creation as defense in depth, including when the directory or files already exist. 4. Refuse to use private-key files that are owned by another user or readable by group or others. 5. Use atomic file creation with exclusive flags to prevent replacement or symlink attacks. 6. Consider storing private keys in an operating-system key store or hardware-backed keystore. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/submit-request.sh:31
Finding
Predictable shared temporary file permits symlink and race-condition attacks<![CDATA[ ## Vulnerability Details **File Location**: `scripts/submit-request.sh:31-49` **Vulnerability Type**: Unsafe temporary-file handling **Risk Level**: Medium ### Vulnerable Code ```bash if [ -n "$PROVIDER_NAME" ] && [ -f "$PROVIDERS_FILE" ]; then # Look up provider by name (case-insensitive) PROVIDER_LOWER=$(echo "$PROVIDER_NAME" | tr '[:upper:]' '[:lower:]') API_KEY=$(node -e " const fs = require('fs'); const data = JSON.parse(fs.readFileSync(process.argv[1], 'utf8')); const search = process.argv[2].toLowerCase(); const match = data.providers.find(p => p.nameLower === search || p.providerName.toLowerCase() === search || p.name.toLowerCase().includes(search) || p.providerName.toLowerCase().includes(search) ); if (match) { console.log(match.apiKey); process.stderr.write(match.name); } " "$PROVIDERS_FILE" "$PROVIDER_NAME" 2>"/tmp/.heysummon-provider-match") RESOLVED_PROVIDER=$(cat /tmp/.heysummon-provider-match 2>/dev/null) rm -f /tmp/.heysummon-provider-match fi ``` ### Technical Analysis The script uses the fixed path `/tmp/.heysummon-provider-match` for temporary output. `/tmp` is normally shared among local users. Shell redirection follows symbolic links and truncates the destination before launching the Node.js process. Because the filename is predictable and shared across all invocations, an attacker can pre-create it as a symbolic link to another file writable by the victim. Concurrent executions can also overwrite or read each other's provider selection data. ### Attack Path 1. A local attacker predicts the fixed temporary path. 2. The attacker creates `/tmp/.heysummon-provider-match` as a symbolic link to a file writable by the victim. 3. The victim invokes `submit-request.sh` with a provider name. 4. Shell redirection opens and truncates the symlink target under the victim's permissions. 5. The Node.js process writes the resolved provider name to that target. 6. ...[truncated 779 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Eliminate the temporary file by returning provider name and API key as structured JSON through a single captured output stream. 2. If a temporary file is unavoidable, create it with `mktemp` in a private directory. 3. Set a restrictive umask such as `077` before creating temporary files. 4. Register a shell `trap` to remove the unique file on exit, interruption, or error. 5. Open temporary files with exclusive creation semantics and reject symbolic links. 6. Avoid running the script with elevated privileges. ]]>
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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (37)

Credential Access

High
Category
Privilege Escalation
Content
2. **Create `.env` file:**
   ```bash
   cp .env.example .env
   # Edit .env with your API key and platform URL
   ```
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
2. **Create `.env` file:**
   ```bash
   cp .env.example .env
   # Edit .env with your API key and platform URL
   ```

3. **Register your first provider:**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
2. **Create `.env` file:**
   ```bash
   cp .env.example .env
   # Edit .env with your API key and platform URL
   ```

3. **Register your first provider:**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
2. **Create `.env` file:**
   ```bash
   cp .env.example .env
   # Edit .env with your API key and platform URL
   ```

3. **Register your first provider:**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
2. **Create `.env` file:**
   ```bash
   cp .env.example .env
   # Edit .env with your API key and platform URL
   ```

3. **Register your first provider:**
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

External Script Fetching

High
Category
Supply Chain
Content
fi

# Fetch provider info
RESPONSE=$(curl -s "${BASE_URL}/api/v1/whoami" -H "x-api-key: ${API_KEY}")
ERROR=$(echo "$RESPONSE" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const j=JSON.parse(d);if(j.error)console.log(j.error)}catch(e){}})" 2>/dev/null)

if [ -n "$ERROR" ]; then
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Credential Access

High
Category
Privilege Escalation
Content
# List registered providers
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
[ -f "$SKILL_DIR/.env" ] && set -a && source "$SKILL_DIR/.env" && set +a

PROVIDERS_FILE="${HEYSUMMON_PROVIDERS_FILE:-$SKILL_DIR/providers.json}"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# List registered providers
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
[ -f "$SKILL_DIR/.env" ] && set -a && source "$SKILL_DIR/.env" && set +a

PROVIDERS_FILE="${HEYSUMMON_PROVIDERS_FILE:-$SKILL_DIR/providers.json}"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# List registered providers
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
[ -f "$SKILL_DIR/.env" ] && set -a && source "$SKILL_DIR/.env" && set +a

PROVIDERS_FILE="${HEYSUMMON_PROVIDERS_FILE:-$SKILL_DIR/providers.json}"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# List registered providers
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
[ -f "$SKILL_DIR/.env" ] && set -a && source "$SKILL_DIR/.env" && set +a

PROVIDERS_FILE="${HEYSUMMON_PROVIDERS_FILE:-$SKILL_DIR/providers.json}"
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

External Script Fetching

High
Category
Supply Chain
Content
mkdir -p "$(dirname "$EVENTS_FILE")"
    local TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    echo "{\"timestamp\":\"$TIMESTAMP\",\"message\":$(node -e "console.log(JSON.stringify(process.argv[1]))" "$MSG" 2>/dev/null)}" >> "$EVENTS_FILE"
    curl -s -X POST "http://127.0.0.1:${OPENCLAW_PORT}/cron/wake" \
      -H "Authorization: Bearer ${OPENCLAW_TOKEN}" \
      -H "Content-Type: application/json" \
      -d "{\"text\":\"$MSG\",\"mode\":\"now\",\"agentId\":\"secondary\"}" \
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# Remove closed/expired requests
      EVENT_TYPE=$(echo "$data" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{console.log(JSON.parse(d).type)}catch(e){}})" 2>/dev/null)
      if [ "$EVENT_TYPE" = "closed" ] && [ -n "$EVENT_REQ_ID" ]; then
        rm -f "$REQUESTS_DIR/$EVENT_REQ_ID"
      fi
    fi
  done < "$FIFO"
Confidence
98% confidence
Finding
The script uses EVENT_REQ_ID derived from untrusted event JSON to build a filesystem path and passes it directly to rm -f. An attacker able to influence requestId could use path traversal values like ../../somefile to delete arbitrary files accessible to the current user, especially because no basename or character validation is enforced.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
}
  " "$PROVIDERS_FILE" "$PROVIDER_NAME" 2>"/tmp/.heysummon-provider-match")
  RESOLVED_PROVIDER=$(cat /tmp/.heysummon-provider-match 2>/dev/null)
  rm -f /tmp/.heysummon-provider-match
fi

# Fallback: if no provider specified or not found, use default from env
Confidence
95% confidence
Finding
The script uses a fixed path in /tmp for intermediate provider data, then reads and deletes it. Because /tmp is shared, another local user or process could pre-create or race this file, causing data spoofing, symlink attacks, or unintended file deletion depending on execution context.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README encourages submitting conversation context and routing notifications through external services, including a human-provider workflow, without a prominent privacy warning about sharing potentially sensitive prompts, messages, or identifiers outside the local agent environment. In a HITL skill, that omission increases the chance users will send secrets, regulated data, or internal context to third parties unintentionally.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The README makes a security claim that API keys are never passed as CLI arguments, but it also documents `add-provider.sh "hs_cli_..."` usage that places a live secret directly in the shell command line. Command-line arguments are commonly exposed through shell history, process listings, audit logs, and terminal recordings, so this inconsistency can cause credential disclosure.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
4. **Restrict file permissions:**
   ```bash
   chmod 600 .env
   chmod 700 .keys/
   ```
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
4. **Restrict file permissions:**
   ```bash
   chmod 600 .env
   chmod 700 .keys/
   ```

---
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script persists the supplied client API key directly into providers.json in plaintext, with no warning, permission hardening, or indication that this creates a local credential store. If that file is later read by other users, checked into source control, or exposed by backups/logging, the key can be reused to impersonate the client and access provider-linked functionality.

Intent-Code Divergence

Medium
Confidence
93% confidence
Finding
The script comment claims it syncs only the heysummon skill, but `git add -A` stages all changes in the repository and the later commit/push publishes them. This mismatch is dangerous because operators may trust the narrower description and unintentionally upload unrelated files, secrets, or work-in-progress content.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The script automatically commits and pushes to `origin main` without any user warning, approval, or review step once changes are detected. In a skill context, this increases the chance of silently publishing unintended modifications or sensitive data, especially if run on a schedule as the comments suggest.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The script writes private signing and encryption keys directly to disk using default filesystem permissions and without restricting access or warning the operator about secure storage. On multi-user systems or in permissive umask environments, this can expose long-term private keys to other local users or accidental inclusion in backups, logs, or repositories, compromising all encrypted communications and signatures.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script intentionally prints the first 12 characters of each stored provider API key to stdout. Even partial credential disclosure is sensitive because prefixes can aid key identification, correlation across systems, leakage into logs or screenshots, and reduce secrecy if other portions are exposed elsewhere.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The header presents the script as a passive SSE listener, but the implementation also fetches full message bodies and forwards notifications through a local tool gateway. That mismatch reduces informed consent and can cause operators to run a component with broader data access and transmission behavior than advertised.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The script reads an unrelated OpenClaw gateway bearer token from the user's home directory and uses it to invoke a separate local tooling API, expanding the trust boundary beyond the stated SSE-watcher role. This creates a covert bridge between HeySummon event data and another privileged local service, so compromise or misuse of event content can trigger actions or expose data through an unrelated channel without explicit consent.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
Reading a local gateway token from the user's OpenClaw config without a user-facing warning silently accesses sensitive credentials belonging to another system. Even if intended for convenience, this violates least surprise and can enable unauthorized use of a privileged local API under the user's identity.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
README.md:423