Back to skill

Security audit

Config Tracker

Security checks for vulnerabilities and agentic risk

Overview

This skill openly tracks OpenClaw configuration files, but it automatically creates Git history for sensitive workspace and home-directory files without enough user control or safeguards.

Review this before installing if your OpenClaw files may contain credentials, private endpoints, personal data, or sensitive agent instructions. Install only if you intentionally want automatic Git history for these files, and consider disabling it or narrowing the tracked file list before use.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
config-tracker.js:31
Finding
Automatic Git Versioning Persistently Retains Sensitive Configuration and Agent Data<![CDATA[ ## Vulnerability Details **File Location**: `config-tracker.js:31-41` and `config-tracker.js:318-361` **Vulnerability Type**: Sensitive-data retention in Git history **Risk Level**: Medium ### Vulnerable Code ```js const DEFAULT_CONFIG = { enabled: true, workspaceFiles: [ "AGENTS.md", "USER.md", "SOUL.md", "MEMORY.md", "TOOLS.md", "HEARTBEAT.md", "IDENTITY.md" ], openclawConfig: "~/.openclaw/openclaw.json", commitMessagePrefix: "auto: track config changes", gitUserName: "OpenClaw Bot", gitUserEmail: "openclaw@localhost" }; ``` ```js async checkAndCommit(workspaceDir) { // Get workspace absolute path const workspacePath = path.resolve(workspaceDir); // 1. Track workspace markdown files const workspaceFiles = this.config.workspaceFiles.map(f => path.join(workspacePath, f)); const existingWorkspaceFiles = await Promise.all( workspaceFiles.map(async (f) => ({ path: f, exists: await fileExists(f) })) ); const validWorkspaceFiles = existingWorkspaceFiles .filter(f => f.exists) .map(f => f.path); if (validWorkspaceFiles.length > 0) { // Ensure git repo exists for workspace await initGitRepo(workspacePath, this.config); const changedWorkspaceFiles = await hasChanges(workspacePath, validWorkspaceFiles); if (changedWorkspaceFiles.length > 0) { await commitChanges(workspacePath, changedWorkspaceFiles, this.config); } } // 2. Track openclaw.json const openclawConfigPath = expandTilde(this.config.openclawConfig); const openclawDir = path.dirname(openclawConfigPath); if (await fileExists(openclawConfigPath)) { // Ensure git repo exists for ~/.openclaw/ await initGitRepo(openclawDir, this.config); const changedConfigFiles = await hasChanges(openclawDir, [openclawConfigPath]); if (changedConfigFiles.length > 0) { await commitChanges(openclawDir, changedConfigFiles, this.config); } } } ``` ### Technical Analys ...[truncated 2302 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not track `openclaw.json`, user records, memory files, or tool configuration by default. Require explicit per-file opt-in. 2. Add secret scanning before staging. Reject commits containing credential patterns such as API keys, bearer tokens, private keys, passwords, and connection strings. 3. Support configurable redaction rules and allow users to maintain an exclusion list for sensitive fields and files. 4. Display a clear warning that Git history retains deleted values and obtain explicit consent before initializing repositories or enabling automatic commits. 5. Consider storing sanitized snapshots in a dedicated repository rather than initializing Git inside live configuration directories. 6. Restrict permissions on generated `.git` directories and ensure backup or synchronization systems do not publish them unintentionally. 7. Document incident-response procedures for revoking exposed credentials and securely rewriting history with tools such as `git filter-repo`. 8. If sensitive versioning is required, encrypt repository contents using a suitable secret-management or encrypted-storage mechanism rather than relying on plain Git objects. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
config-tracker.js:228
Finding
Automatic Commits Include Unrelated Changes Already Present in the Shared Git Index<![CDATA[ ## Vulnerability Details **File Location**: `config-tracker.js:228-250` **Vulnerability Type**: Unrestricted shared-index commit **Risk Level**: Medium ### Vulnerable Code ```js async function commitChanges(repoDir, files, config) { if (files.length === 0) { return; } const timestamp = new Date().toISOString().slice(0, 19).replace("T", " "); log.info(`Committing changes: ${files.join(", ")}`); try { // Add specific files only - never use git add . await gitRun(repoDir, ["add", ...files], { name: config.gitUserName, email: config.gitUserEmail }); // Check if there are staged changes const status = await gitRun(repoDir, ["status", "--porcelain"]); if (!status.trim()) { log.debug("No staged changes to commit"); return; } // Generate change descriptions AFTER staging (so --cached works) const changeSummaries = await getDiffSummary(repoDir, files); // Build commit message with descriptions let message = `${config.commitMessagePrefix} [${timestamp}]`; if (changeSummaries.length > 0) { message += "\n\n" + changeSummaries.map(s => `${s.path} (${s.stats}): ${s.description}` ).join("\n"); } await gitRun(repoDir, ["commit", "-m", message], { name: config.gitUserName, email: config.gitUserEmail }); log.info(`Committed: ${message.split("\n")[0]}`); log.debug(`Full commit message:\n${message}`); } catch (error) { log.error("Error committing changes:", error); } } ``` ### Technical Analysis The plugin limits its `git add` operation to selected files, but the subsequent `git commit` operation is not limited to those paths. A normal Git commit records the complete state of the shared index, including changes staged before the plugin ran. The unrestricted `git status --porcelain` check also examines the overall repository rather than confirming that only the intended paths are staged. The generated summary covers the plugin-selected files, so un ...[truncated 1762 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Isolate automated staging from the user's index by setting `GIT_INDEX_FILE` to a temporary index dedicated to the plugin. 2. Alternatively, create commits restricted to explicit pathspecs, such as `git commit --only -m <message> -- <files>`, after verifying behavior for new and deleted files. 3. Insert `--` before user-configurable path arguments to clearly separate options from paths: ```js await gitRun(repoDir, ["add", "--", ...files], gitConfig); ``` 4. Inspect staged paths with `git diff --cached --name-only -- <files>` and abort if the intended staged set cannot be isolated. 5. Preserve and restore the original index if temporary manipulation is unavoidable, including robust cleanup in a `finally` block. 6. Add integration tests in which unrelated changes are staged before the hook runs and verify that those changes remain staged but uncommitted afterward. 7. Ensure the commit summary is derived from the exact tree content being committed, rather than only from the plugin's expected file list. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The plugin monitors and commits changes to ~/.openclaw/openclaw.json in the user's home directory, outside the active workspace. Tracking and persisting changes in a home-directory config broadens scope beyond the project boundary and may capture sensitive configuration, tokens, endpoints, or personal settings into a local Git history without clear consent.

Ssd 3

Medium
Confidence
96% confidence
Finding
The tracked file list includes highly sensitive natural-language files such as USER.md, SOUL.md, MEMORY.md, and IDENTITY.md, and the skill says these are automatically committed whenever they change. This creates a strong data retention and disclosure risk because personal data, agent memory, internal instructions, or secrets can be durably stored in Git history and later exposed through logs, backups, sync, or repository sharing.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill explicitly states it will automatically initialize Git repositories and create commits on every conversation turn via a hook, without any described user confirmation or prominent warning about persistent history changes. This is dangerous because it silently mutates repository state and creates durable audit/history records that may capture sensitive configuration or prompt-related changes users did not intend to retain.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The skill automatically initializes a Git repository in the workspace and creates commits without explicit user approval. Even if intended for backup/auditing, silently modifying repository state is security-relevant because it changes user files, creates history the user did not request, and may interfere with existing workflows or compliance expectations.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The skill performs automatic staging and commits during a before_prompt_build hook, meaning normal conversation activity can trigger filesystem and repository modifications with no user confirmation. This hidden side effect is dangerous because it violates user expectations, can repeatedly alter local state, and may preserve sensitive content in commit history where deletion is harder.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The manifest registers a before_prompt_build hook, which runs automatically on a broad and sensitive lifecycle event before every prompt is assembled. In the context of a skill described as tracking and committing configuration and markdown changes, this creates a meaningful security risk because the hook can observe or act on workspace and configuration state without an explicit per-use trigger, increasing the chance of unintended data collection or automatic git operations.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The package description is written entirely in Chinese ("自动追踪并提交...") with no indication that language choice is optional or that the skill is region-specific. This can violate language/locale policy because it imposes a specific language in user-facing metadata without documented opt-in or justification.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The manifest description says the skill will automatically track and commit OpenClaw configuration files and key markdown files, but it does not define clear trigger boundaries, file scope, or activation constraints. In a hook-based skill running before prompt build, vague scope can enable unexpected collection or modification of sensitive repository content, increasing the risk of unauthorized commits or overbroad file handling.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The description is written in Chinese and appears to prescribe behavior without any indication of user language preference or opt-in. Forcing or assuming a specific language can reduce transparency for users and reviewers, making it harder to understand that the skill auto-tracks and commits files, which indirectly increases security risk by obscuring impactful behavior.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The natural-language instructions and warnings in this skill are presented only in Chinese. This can violate a language/locale policy when the skill does not offer the user a language choice or document that the locale restriction is intentional and justified.

Natural-Language Policy Violations

Low
Confidence
93% confidence
Finding
The top-level natural-language description is written entirely in Chinese and presents the skill behavior and trigger timing in that language without offering a language choice or documenting a locale-specific justification. This can violate language/locale policy when a skill imposes a specific language absent user opt-in.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The manifest description is written only in Chinese (`自动追踪并提交...`) with no indication that the skill is region-specific or that users can choose their language or locale. This can violate language/locale policy expectations when a skill implicitly enforces a specific language without opt-in.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
config-tracker.js:100