Back to skill

Security audit

OpenClaw Credential Manager

Security checks for vulnerabilities and agentic risk

Overview

This skill has a legitimate credential-management purpose, but it asks for broad control over sensitive local credentials and includes unsafe guidance and scripts that could expose or damage them.

Review carefully before installing. Do not use this as a mandatory cross-skill policy without explicit opt-in, do not store the GPG passphrase in the same .env, do not source generated .env files as shell code unless values are safely serialized, and avoid running cleanup or setup-gpg.sh until you have verified backups and understand the global GPG changes.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (5)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:673
Finding
Mandatory Cross-Skill Enforcement Hijacks Agent and Skill Behavior<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:673-708` **Vulnerability Type**: Cross-skill instruction and execution-policy hijacking **Risk Level**: High ### Vulnerable Code Snippet ```markdown Other OpenClaw skills MUST validate credentials are secure before using them: ### Python Skills ```python #!/usr/bin/env python3 import sys from pathlib import Path # Add credential-manager scripts to path sys.path.insert(0, str(Path.home() / '.openclaw/skills/credential-manager/scripts')) # Enforce secure .env (exits if not compliant) from enforce import require_secure_env, get_credential require_secure_env() # Now safe to load credentials (handles GPG-encrypted keys transparently) api_key = get_credential('SERVICE_API_KEY') wallet_key = get_credential('MAIN_WALLET_PRIVATE_KEY') # Auto-decrypts from GPG ``` ### Bash Skills ```bash #!/usr/bin/env bash set -euo pipefail # Validate .env exists and is secure if ! python3 ~/.openclaw/skills/credential-manager/scripts/enforce.py; then exit 1 fi # Now safe to load source ~/.openclaw/.env ``` **This creates a fail-fast system:** If credentials aren't properly secured, skills refuse to run. Users are forced to fix it. ``` Related mandatory directives also appear in `SKILL.md:3-16` and `CONSOLIDATION-RULE.md:3-11`. ### Technical Analysis The Skill goes beyond offering credential-management functionality and declares authority over all other OpenClaw Skills. It instructs unrelated Skills to import its enforcement module and terminate when its centralized credential policy is not satisfied. The actual enforcement function calls `sys.exit(1)` by default. Consequently, adoption of these instructions gives this Skill control over whether unrelated functionality is permitted to run. This changes the Agent's execution policy merely by loading or following the Skill instructions rather than through an explicit, narrowly scoped user decision. Credential security checks may legitimately be offered to ...[truncated 1111 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove “mandatory,” “no exceptions,” “users are forced,” and similar cross-Skill authority claims. 2. Scope enforcement to credential-consuming code that explicitly opts into this module. 3. Make `require_secure_env()` return a structured result by default rather than terminating the caller. 4. Require explicit user approval before modifying or imposing requirements on other Skills. 5. Document the centralized `.env` design as one supported deployment option, not a universal prerequisite. 6. Allow callers to configure credential locations and required controls without importing global policy. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:614
Finding
Shell Command Injection Through GPG Passphrase in Recommended Node.js Loader<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:614-619` **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code Snippet ```javascript const { execSync } = require('child_process'); const passphrase = process.env.OPENCLAW_GPG_PASSPHRASE || ''; const cmd = passphrase ? `echo "${passphrase}" | gpg -d --batch --quiet --passphrase-fd 0 "${SECRETS_PATH}"` : `gpg -d --batch --quiet "${SECRETS_PATH}"`; const secrets = JSON.parse(execSync(cmd, { encoding: 'utf8' })); ``` ### Technical Analysis The recommended loader interpolates `OPENCLAW_GPG_PASSPHRASE` directly into a command string executed through `execSync()`. Node.js executes string-form `execSync()` through a shell. Double quotes do not prevent command substitution, and a value containing shell syntax can alter the generated command. Examples of dangerous content include command substitution syntax, embedded double quotes, redirection operators, and command separators. This is particularly unsafe because the same documentation recommends storing the passphrase in `~/.openclaw/.env`. Anyone able to influence that file or the process environment can supply the injection payload. The passphrase may also become visible in shell diagnostics or process information because it is embedded in the command text. ### Attack Path 1. An attacker gains the ability to set `OPENCLAW_GPG_PASSPHRASE`, directly or by modifying a sourced `.env` file. 2. The attacker sets it to a value containing shell syntax, such as a command substitution. 3. A Node.js Skill adopts the documented `loadCred()` implementation. 4. The Skill builds a command string containing the hostile value. 5. `execSync()` invokes the system shell. 6. The injected command executes with the privileges and filesystem access of the OpenClaw process. ### Impact Assessment Successful exploitation provides arbitrary local command execution as the account running the affected Skill. This may permit reading al ...[truncated 276 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace string-form `execSync()` with `spawnSync()` or `execFileSync()` using an argument array and no shell. 2. Supply the passphrase through the subprocess's standard input rather than embedding it in a command. 3. Set `shell: false` explicitly. 4. Prefer GPG agent or pinentry integration so application code does not handle the passphrase. 5. Remove the recommendation to save the encryption passphrase beside the encrypted credential references. 6. Add regression tests using passphrases containing quotes, substitutions, spaces, and shell metacharacters. A safer design is: ```javascript const result = spawnSync( 'gpg', ['-d', '--batch', '--quiet', '--passphrase-fd', '0', SECRETS_PATH], { input: passphrase, encoding: 'utf8', shell: false } ); ``` ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/consolidate.py:121
Finding
Unescaped Credential Values Are Written to a File Later Executed as Shell Code<![CDATA[ ## Vulnerability Details **File Location**: `scripts/consolidate.py:121-143, 241-260` **Vulnerability Type**: Stored shell injection through unsafe dotenv serialization **Risk Level**: High ### Vulnerable Code Snippet ```python def load_credentials(path: Path) -> Dict: """Load credentials from a file.""" if path.suffix == '.json': with open(path) as f: data = json.load(f) # Flatten nested dicts for .env compatibility flat = {} for k, v in data.items() if isinstance(data, dict) else []: if isinstance(v, (dict, list)): flat[k] = json.dumps(v, separators=(',', ':')) else: flat[k] = str(v) return flat if flat else (data if isinstance(data, dict) else {}) elif '.env' in path.name: creds = {} with open(path) as f: for line in f: line = line.strip() if '=' in line and not line.startswith('#'): key, val = line.split('=', 1) creds[key.strip()] = val.strip() return creds return {} ``` ```python with open(env_file, 'w') as f: f.write("# OpenClaw Agent Credentials\n") f.write("# Generated by credential-manager skill\n\n") # Group by service services = {} for key, value in sorted(env_data.items()): service = key.split('_')[0] if '_' in key else 'OTHER' if service not in services: services[service] = [] services[service].append((key, value)) for service, items in sorted(services.items()): f.write(f"# {service}\n") for key, value in items: f.write(f"{key}={value}\n") f.write("\n") ``` The generated file is subsequently recommended for execution in `SKILL.md:730-738`: ```bash # Load .env set -a source ~/.openclaw/.env set +a ``` ### Technical Analysis Credential keys and values loaded from discovered JSON or `.env` files are written dir ...[truncated 1652 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Validate every generated key against `^[A-Z_][A-Z0-9_]*$` and reject invalid keys. 2. Reject values containing NUL bytes or unapproved line breaks. 3. Use a maintained dotenv serializer that correctly quotes and escapes values. 4. Treat the output strictly as data and remove all recommendations to execute it with `source`. 5. Load credentials through a parser that never invokes a shell. 6. Show the user each source path before migration and require explicit approval for custom or generic files. 7. Write the new file to a securely created temporary file, validate it, set its permissions, and atomically replace the destination. 8. Add tests covering `$()`, backticks, quotes, semicolons, newlines, variable expansion, and malformed key names. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/encrypt.py:50
Finding
Decryption Failure Can Silently Overwrite Existing Encrypted Secrets<![CDATA[ ## Vulnerability Details **File Location**: `scripts/encrypt.py:50-72, 157-195` **Vulnerability Type**: Fail-open encrypted-store handling and destructive overwrite **Risk Level**: High ### Vulnerable Code Snippet ```python def load_secrets(secrets_file: Path, passphrase: str = None) -> dict: """Decrypt and load existing secrets from GPG file.""" if not secrets_file.exists(): return {} if passphrase is None: passphrase = _get_passphrase() try: result = subprocess.run( ['gpg', '-d', '--batch', '--quiet', '--passphrase-fd', '0', str(secrets_file)], input=passphrase, capture_output=True, text=True, timeout=30 ) if result.returncode == 0: return json.loads(result.stdout) else: print(f"❌ GPG decryption failed: {result.stderr.strip()}", file=sys.stderr) except (subprocess.TimeoutExpired, json.JSONDecodeError) as e: print(f"❌ Failed to load secrets: {e}", file=sys.stderr) return {} ``` ```python # Load existing secrets secrets = load_secrets(secrets_file, passphrase) encrypted = [] not_found = [] for key in key_names: key = key.strip() if key not in env_data: not_found.append(key) continue value = env_data[key] # Skip if already encrypted if value.startswith('GPG:'): print(f" ⏭️ {key}: already encrypted") continue # Move value to secrets secrets[key] = value encrypted.append(key) ... # Save encrypted secrets print(f"\n🔐 Encrypting {len(encrypted)} key(s)...") if not save_secrets(secrets_file, secrets, passphrase): return False ``` `save_secrets()` invokes GPG with `--yes` and writes to the existing destination. ### Technical Analysis When an encrypted secrets file exists but cannot be decrypted—because of a wrong passphrase, corruption, timeout, or invalid JSON—`load_secrets()` logs an error and returns an em ...[truncated 1331 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Raise a fatal exception whenever an existing secrets file cannot be decrypted, parsed, or authenticated. 2. Return an empty dictionary only when the file genuinely does not exist. 3. Encrypt into a unique temporary file created with restrictive permissions. 4. Verify that the temporary ciphertext can be decrypted and parsed before replacement. 5. Atomically replace the destination with `os.replace()` only after successful verification. 6. Keep a protected versioned backup of the prior ciphertext before replacement. 7. Check and propagate the return value of every `save_secrets()` call, including the call in `decrypt_keys()`. 8. Avoid predictable temporary names such as `.env.secrets.tmp`; use `tempfile.mkstemp()` in a mode-700 directory. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/setup-gpg.sh:59
Finding
Skill-Specific Setup Overwrites Global GPG Security Configuration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/setup-gpg.sh:59-93` **Vulnerability Type**: Excessive configuration scope and weakened global secret handling **Risk Level**: Medium ### Vulnerable Code Snippet ```bash GPG_DIR="$HOME/.gnupg" mkdir -p "$GPG_DIR" chmod 700 "$GPG_DIR" AGENT_CONF="$GPG_DIR/gpg-agent.conf" # Backup existing config if [[ -f "$AGENT_CONF" ]]; then cp "$AGENT_CONF" "${AGENT_CONF}.bak" echo " 📦 Backed up existing config" fi # Write agent config cat > "$AGENT_CONF" << EOF # OpenClaw GPG Agent Configuration # Cache passphrase for ${CACHE_HOURS} hours default-cache-ttl ${CACHE_SECONDS} max-cache-ttl ${CACHE_SECONDS} # Allow loopback pinentry (for headless/script usage) allow-loopback-pinentry EOF chmod 600 "$AGENT_CONF" # Configure GPG to use loopback pinentry GPG_CONF="$GPG_DIR/gpg.conf" if ! grep -q "pinentry-mode loopback" "$GPG_CONF" 2>/dev/null; then echo "pinentry-mode loopback" >> "$GPG_CONF" fi echo " ✅ Agent configured (cache: ${CACHE_HOURS}h)" # Reload agent gpgconf --kill gpg-agent 2>/dev/null || true ``` ### Technical Analysis The setup script modifies the user's global `~/.gnupg` configuration rather than creating a Skill-specific GPG home. It completely replaces `gpg-agent.conf`, enables loopback pinentry, sets an eight-hour cache by default, appends a global pinentry policy, and kills the shared GPG agent. These changes affect all GPG keys and clients owned by the user, including unrelated signing, encryption, and authentication workflows. Existing hardening directives in `gpg-agent.conf` are removed from the active configuration. The backup limits recoverability but does not preserve or merge existing policy. The broad change is unnecessary for encrypting one Skill-specific secrets file and exceeds least-privilege configuration scope. ### Attack Path 1. The user follows the documented first-time setup procedure. 2. The script copies the previous agent configuration to a backup a ...[truncated 687 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a dedicated Skill-specific `GNUPGHOME`, for example `~/.openclaw/gnupg`, with mode `0700`. 2. Pass `--homedir` or set `GNUPGHOME` only for this Skill's GPG subprocesses. 3. Do not overwrite the user's global `gpg-agent.conf`. 4. If global changes are unavoidable, display an exact diff and require explicit confirmation. 5. Merge only necessary directives while preserving all existing settings. 6. Avoid global `pinentry-mode loopback`; specify loopback mode only on commands that require it. 7. Minimize the passphrase cache lifetime and make caching opt-in. 8. Validate `--cache-hours` as a bounded non-negative integer before arithmetic or configuration changes. 9. Restore prior settings automatically if setup or the encryption test fails. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (231)

Credential Access

High
Category
Privilege Escalation
Content
There is exactly **ONE** location for all OpenClaw credentials:

```
~/.openclaw/.env
```

**No exceptions.** Not workspace, not skills, not scripts. Root only.
Confidence
96% confidence
Finding
Mandating that all credentials live in '~/.openclaw/.env' creates a single high-value target in a predictable location. If any skill, script, backup process, or local compromise gains read access to that file, all consolidated credentials may be exposed at once.

Credential Access

High
Category
Privilege Escalation
Content
- `~/.openclaw/workspace/skills/*/.env` ❌ → Root
- `~/.openclaw/workspace/skills/*/repo/.env` ❌ → Root
- `~/.openclaw/workspace/scripts/.env` ❌ → Root
- `~/.config/*/credentials.json` ❌ → Root
- Any scattered API key files ❌ → Root

## Enforcement
Confidence
95% confidence
Finding
The rule explicitly instructs scanning and consolidating files such as '~/.config/*/credentials.json' into a single .env file. Broadly harvesting credential files across unrelated tools or services can pull in secrets beyond OpenClaw's scope, increase unnecessary access to sensitive material, and weaken separation between applications.

Credential Access

High
Category
Privilege Escalation
Content
The credential-manager skill enforces this rule:

1. **Scan:** Detects ALL .env files and credential files
2. **Consolidate:** Merges everything into `~/.openclaw/.env`
3. **Cleanup:** Removes scattered files (after backup)
4. **Validate:** Ensures no scattered files remain
Confidence
95% confidence
Finding
The enforcement section describes detecting all credential files, merging them into one location, and removing originals. This operational pattern can over-collect secrets, erase separation of duties, and turn one file compromise into full credential compromise, especially because the skill frames consolidation as mandatory.

Credential Access

High
Category
Privilege Escalation
Content
## For Skill Developers

**DO NOT create .env files in your skill directories.**

Load credentials from root:
Confidence
93% confidence
Finding
The guidance tells all skill developers to load credentials from a shared root secret file. This encourages broad credential exposure across skills, including skills that may only need a subset of secrets, and increases the chance that a compromised or buggy skill can read unrelated credentials.

Credential Access

High
Category
Privilege Escalation
Content
```bash
#!/bin/bash
# Load from root .env
source ~/.openclaw/.env

# Use credentials
Confidence
98% confidence
Finding
The shell example explicitly uses 'source ~/.openclaw/.env', which executes the contents of that file in the current shell. If the .env contains shell metacharacters, command substitutions, or malicious content, sourcing it can execute arbitrary commands in addition to exposing all loaded secrets to the process environment.

Credential Access

High
Category
Privilege Escalation
Content
```python
#!/usr/bin/env python3
# Load from root .env
from pathlib import Path
env_file = Path.home() / '.openclaw' / '.env'
# ... load and use
Confidence
86% confidence
Finding
The Python example directs developers to read a shared root .env file, reinforcing centralized plaintext secret access from any skill code. While less dangerous than shell sourcing, it still promotes broad, predictable access to all credentials from code that may not need them.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill markets itself as a mandatory security foundation with encryption, rotation tracking, deep scanning, permission enforcement, and migration support, but the analysis indicates those controls are missing, partial, or delegated elsewhere. This kind of security overclaim can cause operators to trust the skill, store secrets under false assumptions, and skip compensating controls.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill markets itself as a mandatory security foundation with encryption, rotation tracking, deep scanning, permission enforcement, and migration support, but the analysis indicates those controls are missing, partial, or delegated elsewhere. This kind of security overclaim can cause operators to trust the skill, store secrets under false assumptions, and skip compensating controls.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill markets itself as a mandatory security foundation with encryption, rotation tracking, deep scanning, permission enforcement, and migration support, but the analysis indicates those controls are missing, partial, or delegated elsewhere. This kind of security overclaim can cause operators to trust the skill, store secrets under false assumptions, and skip compensating controls.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill markets itself as a mandatory security foundation with encryption, rotation tracking, deep scanning, permission enforcement, and migration support, but the analysis indicates those controls are missing, partial, or delegated elsewhere. This kind of security overclaim can cause operators to trust the skill, store secrets under false assumptions, and skip compensating controls.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill markets itself as a mandatory security foundation with encryption, rotation tracking, deep scanning, permission enforcement, and migration support, but the analysis indicates those controls are missing, partial, or delegated elsewhere. This kind of security overclaim can cause operators to trust the skill, store secrets under false assumptions, and skip compensating controls.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill markets itself as a mandatory security foundation with encryption, rotation tracking, deep scanning, permission enforcement, and migration support, but the analysis indicates those controls are missing, partial, or delegated elsewhere. This kind of security overclaim can cause operators to trust the skill, store secrets under false assumptions, and skip compensating controls.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill markets itself as a mandatory security foundation with encryption, rotation tracking, deep scanning, permission enforcement, and migration support, but the analysis indicates those controls are missing, partial, or delegated elsewhere. This kind of security overclaim can cause operators to trust the skill, store secrets under false assumptions, and skip compensating controls.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill markets itself as a mandatory security foundation with encryption, rotation tracking, deep scanning, permission enforcement, and migration support, but the analysis indicates those controls are missing, partial, or delegated elsewhere. This kind of security overclaim can cause operators to trust the skill, store secrets under false assumptions, and skip compensating controls.

Credential Access

High
Category
Privilege Escalation
Content
- `~/.local/share/*/credentials.json` — Local share directories

**Sensitive Key Patterns:**
- API keys, access tokens, bearer tokens
- Secrets, passwords, passphrases
- OAuth consumer keys
- Private keys, signing keys, wallet keys
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The documentation says high-value secrets should never exist as plaintext on disk, then later recommends storing the GPG passphrase in the same plaintext .env file. That collapses the protection boundary: anyone who can read the .env can also decrypt the supposedly protected secrets.

Missing User Warnings

High
Confidence
99% confidence
Finding
The instructions explicitly tell users to store the GPG passphrase in the main .env without warning that this defeats much of the benefit of encrypting high-value secrets. Users following the guide would create a single compromise point for both encrypted data and the decryption key.

Ssd 3

High
Confidence
99% confidence
Finding
Recommending the central credential file as storage for the GPG passphrase creates a natural-language secret exfiltration path in the very file meant to centralize credentials. A compromise of that file yields both application credentials and the means to decrypt protected private keys, magnifying blast radius.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# Example: farcaster-credentials.json was manually migrated
cp ~/.openclaw/farcaster-credentials.json ~/.openclaw/backups/credentials-old-YYYYMMDD/farcaster-credentials.json.bak
chmod 600 ~/.openclaw/backups/credentials-old-YYYYMMDD/farcaster-credentials.json.bak
rm ~/.openclaw/farcaster-credentials.json
```

### Step 7: Update Scripts That Referenced Old Files
Confidence
90% confidence
Finding
The documentation includes a direct rm of a credential file after migration. In a skill that already overclaims safety and supports auto-confirm flows, destructive cleanup can cause accidental loss of the only usable credential copy or delete the wrong file if migration/backup validation is incomplete.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The 'secure' Bash and Node examples interpolate or pipe the passphrase into shell commands, exposing it to process arguments, shell history, logs, crash dumps, or child-process capture. This undermines the claimed GPG protection and creates additional plaintext exposure paths for the most sensitive secret.

Credential Access

High
Category
Privilege Escalation
Content
### Use Separate Credentials
```bash
# Development
~/.openclaw/.env.development

# Production
~/.openclaw/.env.production
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
~/.openclaw/.env.development

# Production
~/.openclaw/.env.production

# Never mix environments
```
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
### For Extra Security
```bash
# Encrypt .env with GPG
gpg -c ~/.openclaw/.env

# Decrypt when needed
gpg -d ~/.openclaw/.env.gpg > /tmp/.env
Confidence
89% confidence
Finding
The documentation recommends decrypting secrets into `/tmp/.env`, which is a globally predictable temporary path and may be exposed to other local processes or users depending on system configuration. It also increases the chance of leaving plaintext secrets behind on disk after use.

Credential Access

High
Category
Privilege Escalation
Content
gpg -c ~/.openclaw/.env

# Decrypt when needed
gpg -d ~/.openclaw/.env.gpg > /tmp/.env
```

### Use Secret Managers
Confidence
89% confidence
Finding
This line is part of the same decryption example that writes plaintext credentials to `/tmp/.env`. Storing decrypted secrets in a temporary shared location creates avoidable local exposure and persistence risk.

Credential Access

High
Category
Privilege Escalation
Content
```bash
# 1. Revoke old key in service dashboard
# 2. Generate new key
# 3. Update .env
sed -i 's/old_key/new_key/' ~/.openclaw/.env
# 4. Test
./test_credentials.sh
Confidence
74% confidence
Finding
The incident-response example uses `sed -i 's/old_key/new_key/' ~/.openclaw/.env`, which can place secret values directly in shell history, process arguments, and potentially logs or monitoring tools. That undermines the surrounding guidance about avoiding secret exposure in command lines and terminals.

Static analysis

No suspicious patterns detected.