Back to skill

Security audit

ipeaky

Security checks for vulnerabilities and agentic risk

Overview

This API-key manager is mostly aligned with its purpose, but it includes unsafe key-handling bugs and Stripe payment scripts that deserve review before installation.

Review this skill carefully before installing. Use only test or restricted API keys until the scripts stop passing secrets in command-line arguments, sanitize AppleScript inputs, remove plaintext backups, and separate or disable the Stripe paid-tier scripts. Be aware that stored keys can be made available to other OpenClaw skills that request the same environment variable.

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/store_key_v4.sh:22
Finding

AppleScript Injection Through an Unsanitized Service Name

Content
View full analysis
}" CONFIG_PREFIX="${2:?Usage: store_key_v4.sh }" # --- 1. Single popup — paste everything --- RAW_INPUT=$(osascript <
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/store_key_v4.sh:101
Finding

API Keys Passed as OpenClaw Command-Line Arguments

Content
View full analysis
/dev/null; then STORED=$((STORED + 1)) else FAILED=$((FAILED + 1)) echo "WARN: Failed to set ${CONFIG_PATH}" fi done < <(echo "$PARSE_RESULT" | python3 -c " import sys, json d = json.load(sys.stdin) for k, v in d.get('keys', {}).items(): print(f'{k}|{v}') ") ``` ### Technical Analysis The complete API key is supplied as the positional command-line argument `"$KEY_VAL"` to `openclaw config set`. Command-line arguments can be exposed through process-inspection utilities, endpoint monitoring, crash reporting, audit systems, and diagnostic collection. The same script also exports all pasted credentials through `IPEAKY_RAW` at lines 42-44: ```bash export IPEAKY_RAW="$RAW_INPUT" PARSE_RESULT=$(python3 -c '...') ``` Consequently, the implementation contradicts its documented guarantee that keys never appear in command arguments or process information. ### Attack Path 1. A user enters one or more API keys through the v4 dialog. 2. The script parses each key into `KEY_VAL`. 3. The full credential is included in the argument vector of an `openclaw` child process. 4. A concurrent local process monitor, audit agent, diagnostic tool, or sufficiently privileged local account records the command line. 5. The observer recovers the full credential and uses it against the corresponding provider. ### Impact Assessment The exposed privileges are those granted to each affected API key. Depending on the key, this may include paid API usage, access to provider data, modification of remote resources, or account-level Stripe operations. Expo ...[truncated 66 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/test_key_v5.sh:34
Finding

Stored API Key Passed to Python Through the Process Argument Vector

Content
View full analysis
/dev/null | tr -d '[:space:]') if [ -z "$KEY" ]; then echo "❌ Could not read key at config path: $CONFIG_PATH" exit 1 fi MASKED="${KEY:0:4}****" # ── 4. Build secure temp header file ────────────────────────────────── HFILE=$(mktemp) chmod 600 "$HFILE" # Replace {{KEY}} in each header line and write to temp file _PYEOF_HDR=$(mktemp /tmp/ipeaky_hdr_XXXXXX.py) cat > "$_PYEOF_HDR" <<'PYEOF' import sys, json config_file = sys.argv[1] key = sys.argv[2] config = json.load(sys.stdin) headers = config.get("headers", []) with open(config_file, "w") as f: for h in headers: f.write(h.replace("{{KEY}}", key) + "\n") PYEOF echo "$CONFIG_JSON" | python3 "$_PYEOF_HDR" "$HFILE" "$KEY" rm -f "$_PYEOF_HDR" ``` ### Technical Analysis Despite the comment stating that the key is never passed as a command-line argument, `"$KEY"` is supplied directly as `sys.argv[2]` to Python. The credential therefore appears in the Python process's argument vector while the header file is generated. Using a mode-0600 header file protects the later `curl` invocation from directly exposing the header in its arguments, but it does not correct the earlier Python argument disclosure. ### Attack Path 1. The testing script reads a stored API key from OpenClaw configuration. 2. It launches Python with the complete key as its third shell argument. 3. During that process's lifetime, process-inspection or monitoring software captures the argument vector. 4. The full API key is recovered despite only a masked value being printed by the script. 5. The recovered key can be replayed directly a ...[truncated 300 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
paid_tier/stripe-checkout.sh:100
Finding

Stripe Secret Key Exposed in Curl Command-Line Arguments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/store_key_v3.sh:41
Finding

Plaintext API Key Temporary Files and Backups Can Survive Storage Failures

Content
View full analysis
"$TEMP_KEY_FILE" KEY_VALUE="" # Clear from shell memory immediately # Locate openclaw config file OPENCLAW_CONFIG="${HOME}/.openclaw/openclaw.json" if [ ! -f "$OPENCLAW_CONFIG" ]; then echo "ERROR: openclaw.json not found at $OPENCLAW_CONFIG" rm -f "$TEMP_KEY_FILE" exit 1 fi ``` The Python update also creates a persistent backup: ```python # Atomic-ish write: backup then overwrite shutil.copy2(config_file, config_file + '.bak.ipeaky') with open(config_file, 'w') as f: json.dump(config, f, indent=2) ``` Cleanup occurs only near the end: ```bash # --- 4. Secure cleanup: overwrite temp file with random data before deletion --- dd if=/dev/urandom of="$TEMP_KEY_FILE" bs=1024 count=1 2>/dev/null || true rm -f "$TEMP_KEY_FILE" ``` ### Technical Analysis The script does not register a shell `trap` after creating the secret-bearing temporary file. A signal, forced termination, shell error, or unexpected failure before the final cleanup leaves the file on disk. The Python update additionally copies the complete OpenClaw configuration to `openclaw.json.bak.ipeaky`. During multi-path updates, later backups can contain credentials written by earlier loop iterations. This creates another persistent plaintext copy outside the active configuration. The project itself performs no encryption of these JSON values, making the statement in `paid_tier/stripe-setup.sh:52` that the key is “encrypted at rest by OS keychain” unsupported by the reviewed implementation. ### Attack Path 1. A user enters a credential through the v3 secure dialog. 2. The script writes the credential to a temporary file. 3. The script is interrupted or exits unexpectedly before lines 1 ...[truncated 550 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:14
Finding

Automatic Environment Injection Breaks Per-Skill Least Privilege

Content
View full analysis
Remediation
View remediation
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
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
Findings (67)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill also performs audit/test-suite functions and optional live validation beyond direct key management, then its declared purpose is too narrow for its effective behavior. That matters because users may invoke it expecting local secret management only, while broader inspection or live API activity can expose sensitive data paths and expand attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the skill also performs audit/test-suite functions and optional live validation beyond direct key management, then its declared purpose is too narrow for its effective behavior. That matters because users may invoke it expecting local secret management only, while broader inspection or live API activity can expose sensitive data paths and expand attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

If the skill also performs audit/test-suite functions and optional live validation beyond direct key management, then its declared purpose is too narrow for its effective behavior. That matters because users may invoke it expecting local secret management only, while broader inspection or live API activity can expose sensitive data paths and expand attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

If the skill also performs audit/test-suite functions and optional live validation beyond direct key management, then its declared purpose is too narrow for its effective behavior. That matters because users may invoke it expecting local secret management only, while broader inspection or live API activity can expose sensitive data paths and expand attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

If the skill also performs audit/test-suite functions and optional live validation beyond direct key management, then its declared purpose is too narrow for its effective behavior. That matters because users may invoke it expecting local secret management only, while broader inspection or live API activity can expose sensitive data paths and expand attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the skill also performs audit/test-suite functions and optional live validation beyond direct key management, then its declared purpose is too narrow for its effective behavior. That matters because users may invoke it expecting local secret management only, while broader inspection or live API activity can expose sensitive data paths and expand attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the skill also performs audit/test-suite functions and optional live validation beyond direct key management, then its declared purpose is too narrow for its effective behavior. That matters because users may invoke it expecting local secret management only, while broader inspection or live API activity can expose sensitive data paths and expand attack surface.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the skill also performs audit/test-suite functions and optional live validation beyond direct key management, then its declared purpose is too narrow for its effective behavior. That matters because users may invoke it expecting local secret management only, while broader inspection or live API activity can expose sensitive data paths and expand attack surface.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

This script materially exceeds the declared purpose of an API-key-management skill by implementing paid-tier monetization logic and creating Stripe Checkout sessions. In an agent skill context, this scope expansion is dangerous because it introduces financial transaction capability, external side effects, and secret use that a user or reviewer would not reasonably expect from the stated functionality.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script performs live external payment-processing actions unrelated to the stated key-management role, including creating Stripe Checkout sessions using a stored secret key. In the skill context, this is especially risky because it enables unexpected monetization actions and external network effects under the guise of credential management.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · paid_tier/stripe-setup.sh (reported line 52)May include surrounding context.

sh
echo "✅ Stripe key stored successfully!"
    echo ""
    echo "Next steps:"
    echo "  • Your key is now in openclaw.json (encrypted at rest by OS keychain)"
    echo "  • Skills can access it via STRIPE_SECRET_KEY env var"
    echo "  • Run: bash paid_tier/stripe-checkout.sh  to test a checkout session"
    echo ""

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script claims the key never appears in process listings, but it passes the raw API key as argv to a Python subprocess: python3 "$ _PYEOF_HDR" "$HFILE" "$KEY". On many systems, local users or monitoring tools can read process arguments via ps or /proc, exposing the secret. In a key-management skill, this contradiction is especially dangerous because users rely on the tool specifically to prevent key disclosure.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The inline comment states the key is never passed as a CLI argument to external tools, but the subsequent call passes $KEY directly to Python as a command-line argument. This creates a local secret exposure channel through process listings and diagnostic tooling. Because the skill's purpose is secure API key handling, this misimplementation undermines its core security guarantees.

Content

No source excerpt is available for this finding.

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/test_key_v5.sh (reported line 65)May include surrounding context.

sh
echo "$CONFIG_JSON" | python3 "$_PYEOF_HDR" "$HFILE" "$KEY"
rm -f "$_PYEOF_HDR"

# ── 5. Run curl ────────────────────────────────────────────────────────
RESP_FILE=$(mktemp)
START_MS=$(python3 -c "import time; print(int(time.time() * 1000))")

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · tests/run_tests.sh (reported line 139)May include surrounding context.

sh
echo "--- SKILL.md security audit ---"

# T14: SKILL.md warns against echoing keys
echo "T14: SKILL.md has NEVER-echo rule"
if grep -qi "NEVER echo\|NEVER include.*key.*chat\|never.*print.*key" SKILL.md; then
  pass "NEVER-echo rule documented"
else

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · tests/run_tests.sh (reported line 141)May include surrounding context.

sh
echo "--- SKILL.md security audit ---"

# T14: SKILL.md warns against echoing keys
echo "T14: SKILL.md has NEVER-echo rule"
if grep -qi "NEVER echo\|NEVER include.*key.*chat\|never.*print.*key" SKILL.md; then
  pass "NEVER-echo rule documented"
else

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
100% 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 · tests/run_tests.sh (reported line 249)May include surrounding context.

sh
# T28: SERVICE_NAME sanitization — runtime test with dangerous input
echo "T28: SERVICE_NAME sanitization blocks dangerous chars at runtime"
DANGEROUS='Evil$(rm -rf /)'
SANITIZED=$(echo "$DANGEROUS" | sed 's/["`$;\\|&<>(){}]/_/g' | tr -s '_')
if echo "$SANITIZED" | grep -qE '[$`\\;|&<>(){}]'; then
  fail "Dangerous chars survived sanitization: $SANITIZED"

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% 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 · tests/run_tests.sh (reported line 249)May include surrounding context.

sh
# T28: SERVICE_NAME sanitization — runtime test with dangerous input
echo "T28: SERVICE_NAME sanitization blocks dangerous chars at runtime"
DANGEROUS='Evil$(rm -rf /)'
SANITIZED=$(echo "$DANGEROUS" | sed 's/["`$;\\|&<>(){}]/_/g' | tr -s '_')
if echo "$SANITIZED" | grep -qE '[$`\\;|&<>(){}]'; then
  fail "Dangerous chars survived sanitization: $SANITIZED"

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README makes absolute claims like 'Keys never touch chat history, command arguments, or logs. Ever.' while later describing stdout handling and network-based validation. Even if the implementation is careful, absolute security guarantees in documentation are unsafe because they can cause operators to overtrust the tool and use it in contexts where stdout capture, agent logging, or remote API testing may expose secrets.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README states or strongly implies that keys are not externally transmitted, but the documented 'test key' workflow sends the provided credential to the provider API for validation. This mismatch can mislead users into performing a network operation they may not expect, which matters because API keys are highly sensitive secrets and external transmission changes the trust and threat model.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill declares shell, file read/write, and environment-related capabilities through its documented behavior, but it does not declare an explicit tool scope or allowed-tools boundary. For a credential-management skill, this increases risk because the agent may invoke powerful primitives without a least-privilege contract, making accidental secret exposure, config tampering, or command misuse more likely.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Broad trigger phrases like 'manage keys' or 'set up API key' can cause the skill to activate in contexts where a user did not intend credential operations. For a secret-handling skill, accidental invocation is more dangerous than usual because it may prompt for, read, store, test, or mutate credentials and config unexpectedly.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation claims keys never touch the network in the preferred flow, yet later instructs using those same keys in outbound curl requests to third-party APIs for testing. This is dangerous because users may rely on a strong confidentiality guarantee that is not universally true, leading to uninformed disclosure of credentials to external services.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The OpenAI test example sends the configured credential over the network to api.openai.com. This is expected for validation, but it remains a genuine external transmission of a secret and should be treated as such in a key-management skill.

Content

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

md
## Testing a Key

Test endpoints:
- **OpenAI**: `curl -s -H "Authorization: Bearer $KEY" https://api.openai.com/v1/models | head`
- **ElevenLabs**: `curl -s -H "xi-api-key: $KEY" https://api.elevenlabs.io/v1/user`
- **Anthropic**: `curl -s -H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" https://api.anthropic.com/v1/messages -d '{"model":"claude-3-haiku-20240307","max_tokens":1,"messages":[{"role":"user","content":"hi"}]}'`
- **Brave Search**: `curl -s -H "X-Subscription-Token: $KEY" "https://api.search.brave.com/res/v1/web/search?q=test&count=1"`

External Transmission

Medium
Category
Data Exfiltration
Confidence
93% confidence
Finding

The ElevenLabs test example transmits the API key to api.elevenlabs.io in an authentication header. This is a real exposure event to an external service and contradicts any blanket implication that keys remain strictly local.

Content

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

md
Test endpoints:
- **OpenAI**: `curl -s -H "Authorization: Bearer $KEY" https://api.openai.com/v1/models | head`
- **ElevenLabs**: `curl -s -H "xi-api-key: $KEY" https://api.elevenlabs.io/v1/user`
- **Anthropic**: `curl -s -H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" https://api.anthropic.com/v1/messages -d '{"model":"claude-3-haiku-20240307","max_tokens":1,"messages":[{"role":"user","content":"hi"}]}'`
- **Brave Search**: `curl -s -H "X-Subscription-Token: $KEY" "https://api.search.brave.com/res/v1/web/search?q=test&count=1"`

Static analysis

No suspicious patterns detected.