Back to skill

Security audit

credential-exposure-map

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed credential-audit tool, but it scans many sensitive local sources and leaves a persistent map of credential locations and prefixes.

Install only if you intentionally want a broad local credential exposure audit. Review the source first, run it in a controlled workspace, expect it to inspect agent config and memory, and delete or protect ~/.openclaw/credential-exposure-report.json after use because it can reveal where valuable secrets are stored.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

other

Warning
Location
scripts/scan_exposure.py:56
Finding

Broad Credential Reconnaissance Creates a High-Value Persistent Exposure Map

Content
View full analysis
12 and bool(re.match(r'^[a-zA-Z0-9/+=_-]+$', value)) if is_secret_name and value: findings.append({ "source": "env_var", "location": key, "type": "environment_variable", "preview": value[:8] + "***" if len(value) > 8 else "***", "risk_score": 55, "risk_reason": "Accessible to all skills via exec", }) return findings ``` The same scan also reads configuration, environment files, persistent memory, MCP configuration, and Git history. All findings are then consolidated into a persistent report: ```python report = { "scan_time": datetime.now(timezone.utc).isoformat(), "workspace": WORKSPACE, "total_findings": len(deduped), "risk_distribution": { "critical": sum(1 for f in deduped if f.get("risk_score", 0) >= 70), "high": sum(1 for f in deduped if 50 <= f.get("risk_score", 0) < 70), "medium": sum(1 for f in deduped if 30 <= f.get("risk_score", 0) < 50), "low": sum(1 for f in deduped if f.get("risk_score", 0) < 30), }, "findings": deduped, } os.makedirs(OPENCLAW_DIR, exist_ok=True) with open(REPORT_PATH, 'w', encoding='utf-8') as f: json.dump(report, f, indent=2) os.chmod(REPORT_PATH, 0o600) ``` ### Technical Analysis The Skill systematically enumerates credential-related data across multiple sensitive domains: - Process environment variables - `~/.openclaw/openclaw.jso ...[truncated 2419 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/scan_exposure.py:359
Finding

Predictable Report Path Allows Symlink-Based File Overwrite

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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (19)

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The skill's stated purpose is to enumerate credentials from env vars, .env files, memory, config, MCP auth, and git history, which is inherently sensitive credential access. Even if intended for defensive auditing, this concentrates secret discovery into one workflow and can expose a broad credential inventory if triggered by mistake, abused by a malicious user, or if the resulting report is mishandled.

Content

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

md
|--------|--------------|
| Environment variables | API keys, tokens, passwords in process.env |
| openclaw.json | Provider keys, webhook secrets, MCP auth |
| .env files | Any .env in workspace or ~/.openclaw |
| MEMORY.md / memory/*.md | Credentials written into agent memory |
| memory/*.json | Credential caches, state files with tokens |
| Installed skills | Skills with exec, read, or network capabilities |

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
99% confidence
Finding

The code iterates through all environment variables and identifies likely secrets, which is direct credential harvesting behavior. Even though it only stores masked previews, the act of enumerating accessible secrets confirms what credentials exist and where, enabling follow-on theft or exfiltration by this or another component.

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 48)May include surrounding context.

python
def scan_env_vars():
    """Scan process.env for credential-like variables."""
    findings = []
    for key, value in os.environ.items():
        key_upper = key.upper()
        is_secret_name = any(s in key_upper for s in ENV_SECRET_NAMES)
        looks_like_secret = len(value) > 12 and bool(re.match(r'^[a-zA-Z0-9/+=_-]+$', value))

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The function targets .env files, which are standard credential containers, so this is direct access to sensitive material rather than a generic file read. Given the skill's goal of mapping all accessible credentials, this behavior is more dangerous because it systematically inventories secrets across common storage locations.

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 104)May include surrounding context.

python
def scan_env_files():
    """Scan .env files for credentials."""
    findings = []
    search_paths = [
        os.path.join(WORKSPACE, ".env"),

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The explicit inclusion of WORKSPACE/.env.local targets another common secret file used for local overrides, often containing developer or staging credentials. Accessing it expands the scope of credential harvesting and may capture secrets users intentionally kept out of tracked config.

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 107)May include surrounding context.

python
"""Scan .env files for credentials."""
    findings = []
    search_paths = [
        os.path.join(WORKSPACE, ".env"),
        os.path.join(WORKSPACE, ".env.local"),
        os.path.join(OPENCLAW_DIR, ".env"),
    ]

Credential Access

High
Category
Privilege Escalation
Confidence
97% confidence
Finding

The explicit inclusion of ~/.openclaw/.env reaches outside the workspace into agent-level configuration, likely containing platform-wide secrets. This broadens the blast radius from project secrets to agent infrastructure credentials, making the skill substantially more dangerous.

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 108)May include surrounding context.

python
findings = []
    search_paths = [
        os.path.join(WORKSPACE, ".env"),
        os.path.join(WORKSPACE, ".env.local"),
        os.path.join(OPENCLAW_DIR, ".env"),
    ]
    search_paths += glob.glob(os.path.join(WORKSPACE, ".env*"))

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The wildcard expansion over .env files increases credential access from a few named files to any matching secret file in the workspace. This is a strong signal of broad secret harvesting because it is designed to discover and read additional credential stores automatically.

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 109)May include surrounding context.

python
search_paths = [
        os.path.join(WORKSPACE, ".env"),
        os.path.join(WORKSPACE, ".env.local"),
        os.path.join(OPENCLAW_DIR, ".env"),
    ]
    search_paths += glob.glob(os.path.join(WORKSPACE, ".env*"))

MCP Config Access

High
Category
Agent Snooping
Confidence
93% confidence
Finding

Reading MCP server configuration exposes integration topology and whether authentication material is present, which can reveal additional secret-bearing systems the agent can reach. In this skill, that access is especially sensitive because the tool's stated purpose is to map all credentials and reachable sources, effectively building a reconnaissance inventory.

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 249)May include surrounding context.

python
def scan_mcp_servers():
    """List MCP servers from config."""
    findings = []
    if not os.path.exists(CONFIG_PATH):
        return findings

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 325)May include surrounding context.

python
scanners = [
        ("Environment Variables", scan_env_vars),
        ("OpenClaw Config", scan_config),
        (".env Files", scan_env_files),
        ("Memory Files (MD)", scan_memory_files),
        ("Memory Files (JSON)", scan_memory_json),
        ("Installed Skills", scan_skills),

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill invokes a Python scanner and describes broad access to environment variables, config files, memory, skills, MCP configuration, and git history, but it declares no explicit tool scope or permissions boundary. In practice this creates hidden high-privilege behavior, making it easier for the skill to overreach or be repurposed to harvest sensitive data without clear user/admin approval.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The phrase "what can my agent access" is ambiguous and could be used in many benign contexts, yet this skill interprets it as authorization to perform a sensitive credential audit. Because the skill is designed to enumerate secrets and capability surfaces, ambiguous activation materially raises the risk of unintended disclosure.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The phrase "what can my agent access" is ambiguous and could be used in many benign contexts, yet this skill interprets it as authorization to perform a sensitive credential audit. Because the skill is designed to enumerate secrets and capability surfaces, ambiguous activation materially raises the risk of unintended disclosure.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The skill persists a credential exposure report to ~/.openclaw/credential-exposure-report.json, creating a durable index of sensitive credential presence, source locations, and risk. Even with 600 permissions and masked values, the report can still reveal secret existence, file paths, service usage, and high-value targets across sessions, increasing post-compromise impact.

Content

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

md
### Skill Capability Matrix

Table showing each installed skill with exec/read/network/write permissions and risk score.

## Security Considerations

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This function is explicitly designed to scan .env files for secrets, representing intentional filesystem enumeration of sensitive credential stores. Because .env files commonly contain production tokens, database passwords, and API keys, this is a meaningful confidentiality risk in the skill context.

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 104)May include surrounding context.

python
def scan_env_files():
    """Scan .env files for credentials."""
    findings = []
    search_paths = [
        os.path.join(WORKSPACE, ".env"),

File System Enumeration

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The glob over .env* enumerates likely secret-bearing files across the workspace, broadening access beyond a single known file into all similarly named environment files. In a credential-audit skill, this materially increases sensitivity because it discovers hidden or secondary secret stores that users may not expect to be scanned.

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 111)May include surrounding context.

python
os.path.join(WORKSPACE, ".env.local"),
        os.path.join(OPENCLAW_DIR, ".env"),
    ]
    search_paths += glob.glob(os.path.join(WORKSPACE, ".env*"))
    
    seen = set()
    for path in search_paths:

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill enumerates all installed skills and infers their execution, network, and write capabilities, which goes beyond credential mapping into broader capability reconnaissance. This information can help an attacker identify the best exfiltration or persistence path once the report is available.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 285)May include surrounding context.

python
return findings
    
    try:
        result = subprocess.run(
            ["git", "-C", WORKSPACE, "log", "--oneline", "-200", "--all"],
            capture_output=True, text=True, timeout=10
        )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/scan_exposure.py (reported line 290)May include surrounding context.

python
capture_output=True, text=True, timeout=10
        )
        # Check diffs for secrets in last 50 commits
        result = subprocess.run(
            ["git", "-C", WORKSPACE, "log", "-50", "--patch", "--format=", "--all"],
            capture_output=True, text=True, timeout=15
        )

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill persists a consolidated credential exposure report to disk under ~/.openclaw, creating a new high-value artifact that aggregates sensitive metadata about accessible secrets and their locations. Even with mode 0600, this increases attack surface because other local processes, future skills, backups, or accidental disclosure can expose the inventory.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script writes a credential exposure report to persistent storage without any explicit warning, consent, or confirmation, despite handling highly sensitive information. Silent persistence of such a report can surprise users and leaves behind a durable map of secrets and access paths that may later be discovered or exfiltrated.

Content

No source excerpt is available for this finding.