-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Labels
enhancementNew feature or requestNew feature or requestsecuritySecurity-related issueSecurity-related issue
Description
Summary
The forensic analysis documents that traditional malware families (RedLine, Lumma, Vidar) have adapted their search routines to specifically target OpenClaw's unique directory structures. These infostealers now look for:
~/.openclaw/credentials.json(API keys, session tokens)~/.openclaw/wallet.json(crypto wallet data)~/.openclaw/.env(environment secrets)~/.clawdbot/.env(legacy path from pre-rebrand era)~/.clawdbot/credentials.json(legacy path)
Currently, scan_secrets.py scans ~/.openclaw/ but does not check:
- Legacy
~/.clawdbot/paths (from the Clawdbot/Moltbot rebrand era) credentials.jsonspecificallywallet.jsonspecifically- Signal messenger pairing credentials (found in the O'Reilly scan)
Gap Analysis
Current scan_secrets.py scans these paths:
~/.openclaw/openclaw.json -- CHK-SEC-001
~/.openclaw/exec-approvals.json -- CHK-SEC-002
~/.openclaw/.clawtasks/ -- CHK-SEC-003
~/.openclaw/skills/ -- CHK-SEC-003
~/.openclaw/cron/jobs.json -- CHK-SEC-004
~/Library/LaunchAgents/*.plist -- CHK-SEC-005
~/.openclaw/.env -- CHK-SEC-006
Missing paths (high-value infostealer targets):
~/.openclaw/credentials.json -- Contains API keys for Anthropic, OpenAI, Slack
~/.openclaw/wallet.json -- Contains cryptocurrency wallet data
~/.clawdbot/.env -- Legacy path, may still contain live secrets
~/.clawdbot/credentials.json -- Legacy path
~/.clawdbot/config.json -- Legacy path
~/.moltbot/.env -- Moltbot-era legacy path
~/.moltbot/credentials.json -- Moltbot-era legacy path
~/.openclaw/signal/ -- Signal pairing credentials (O'Reilly scan)
/tmp/openclaw-* -- Temporary files with secrets (O'Reilly scan)
Proposed Changes
1. Add check_credentials_json() -- CHK-SEC-009
def check_credentials_json(config_dir: str, findings: Findings):
"""CHK-SEC-009: Credentials file with API keys."""
for fname in ("credentials.json", "creds.json"):
fp = os.path.join(config_dir, fname)
if os.path.isfile(fp):
check_file_permissions(fp, findings, "CHK-SEC-009")
scan_json_file(fp, findings, "CHK-SEC-009", "critical", fname)2. Add check_wallet_json() -- CHK-SEC-010
def check_wallet_json(config_dir: str, findings: Findings):
"""CHK-SEC-010: Cryptocurrency wallet data."""
fp = os.path.join(config_dir, "wallet.json")
if os.path.isfile(fp):
findings.add(
"CHK-SEC-010", "critical",
"Cryptocurrency wallet file found",
f"File {fp} exists in the OpenClaw config directory. "
"Wallet files should never be stored alongside agent configuration.",
f"file={fp}",
"Move wallet data to a hardware wallet or encrypted vault.",
)3. Add check_legacy_paths() -- CHK-SEC-011
LEGACY_DIRS = [
os.path.expanduser("~/.clawdbot"), # Original Clawdbot
os.path.expanduser("~/.moltbot"), # Moltbot rebrand era
]
def check_legacy_paths(findings: Findings):
"""CHK-SEC-011: Legacy config directories with live secrets."""
for legacy_dir in LEGACY_DIRS:
if os.path.isdir(legacy_dir):
findings.add(
"CHK-SEC-011", "warn",
f"Legacy config directory exists: {legacy_dir}",
f"Directory {legacy_dir} is from a previous OpenClaw rebrand. "
"It may contain stale API keys and credentials that are still valid.",
f"directory={legacy_dir}",
f"Audit {legacy_dir} for secrets, rotate any found, then remove the directory.",
)
# Also scan for secrets within
for fname in (".env", "credentials.json", "creds.json", "config.json"):
fp = os.path.join(legacy_dir, fname)
if os.path.isfile(fp):
scan_json_file(fp, findings, "CHK-SEC-011", "critical", f"legacy {fname}")4. Add check_temp_files() -- CHK-SEC-012
def check_temp_files(findings: Findings):
"""CHK-SEC-012: Temporary files with potential secrets."""
import tempfile
tmp_dir = tempfile.gettempdir()
for pattern in ("openclaw-*", "clawdbot-*", "moltbot-*"):
for fpath in globmod.glob(os.path.join(tmp_dir, pattern)):
if os.path.isfile(fpath):
fstat = os.stat(fpath)
mode = fstat.st_mode
if mode & (stat.S_IROTH | stat.S_IWOTH):
findings.add(
"CHK-SEC-012", "critical",
f"World-readable temp file: {os.path.basename(fpath)}",
f"Temporary file {fpath} is readable by all users. "
"The O'Reilly scan found Signal credentials in such files.",
f"file={fpath} mode={oct(mode & 0o777)}",
f"Remove the file or restrict permissions: chmod 600 {fpath}",
)Infostealer Target Matrix
| File Path | Targeted By | Data Exposed | Priority |
|---|---|---|---|
~/.openclaw/credentials.json |
RedLine, Lumma, Vidar | API keys, OAuth tokens | Critical |
~/.openclaw/wallet.json |
Vidar, custom stealers | Crypto private keys | Critical |
~/.clawdbot/.env |
Lumma (legacy path scan) | All env secrets | Critical |
~/.openclaw/signal/ |
Custom exfil tools | Signal pairing creds | High |
/tmp/openclaw-* |
Opportunistic scanners | Session tokens, temp keys | High |
~/.moltbot/ |
Legacy path scanners | Pre-rebrand credentials | Medium |
References
- Forensic analysis: "Malware Evolution: Adapting to Agentic Structures"
- O'Reilly internet scan: "Signal messenger pairing credentials found in globally readable temporary files"
malicious-patterns.jsonclawhavoc_indicators.file_targets already lists~/.openclaw/credentials.json- Forensic analysis: "Domain and brand churn" creating legacy path exposure
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestsecuritySecurity-related issueSecurity-related issue