Back to skill

Security audit

Config Modification

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent local OpenClaw config guard, but its automatic watcher and rollback workflow have material scoping, secret-exposure, and recovery-safety issues users should review before installing.

Install only if you are comfortable with a persistent local watcher that can automatically modify OpenClaw configuration and restart the Gateway. Before production use, require explicit path scoping to ~/.openclaw, redact diff output for token/password/API-key fields, bind snapshots and rollback to the exact validated file, and change validation infrastructure failures to fail closed rather than accepting the change.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
quad_check.py:290
Finding
Sensitive Configuration Values Are Exposed Through Diff Output<![CDATA[ ## Vulnerability Details **File Location**: `quad_check.py:290-292`, with the output sink at `quad_check.py:441-443` **Vulnerability Type**: Plaintext exposure of sensitive configuration values **Risk Level**: High ### Vulnerable Code ```python else: diff["changed"].append({ "path": current_path, "old": str(old[key])[:100], "new": str(new[key])[:100] }) ``` The command-line interface subsequently serializes the complete results: ```python summary = qc.get_summary() print("\n=== Quad Check Summary ===") print(json.dumps(summary, indent=2, ensure_ascii=False)) ``` ### Technical Analysis The recursive diff implementation stores the raw previous and current values of every changed non-dictionary field. It applies only a 100-character length limit and does not redact values based on their key names or locations. OpenClaw configuration files can contain credentials such as channel tokens, API keys, passwords, authorization headers, and provider secrets. The project itself references fields such as `channels.discord.token`, `apiKeys`, and `credentials`. Changes to these fields therefore place the old and new secret values in the `CheckResult.details` structure. When `quad_check.py` is invoked directly, `get_summary()` includes these details and the CLI prints the resulting JSON to standard output. Applications importing this module can also inadvertently forward or persist the unredacted summary. This behavior contradicts the declared security boundary that the Skill does not directly access credentials or API keys. ### Attack Path 1. A user changes a token, API key, password, or other secret in an OpenClaw JSON configuration file. 2. A previous snapshot containing the old value exists. 3. The user or an automated process invokes: ```bash python3 quad_check.py ~/.openclaw/openclaw.json ``` 4. `_compute_diff()` records up to 100 characters of both the old and new values. 5. `get_summary()` includes the unr ...[truncated 698 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never include raw configuration values in diff results by default. Report only: - The configuration path. - Whether the field was added, removed, or changed. - The value type, if operationally necessary. 2. Recursively redact fields whose names contain terms such as: - `token` - `secret` - `password` - `credential` - `apiKey` - `authorization` - `privateKey` 3. Treat arrays and nested structures as sensitive because credentials may appear inside them. 4. If value-level diagnostics are required, make them an explicit opt-in debug mode and display a prominent warning. 5. Ensure debug output remains redacted unless the user explicitly requests local secure output. 6. Add automated tests confirming that current and historical secret values never appear in: - `CheckResult.details` - `get_summary()` - CLI output - Log files 7. Review existing logs and transcripts for previously exposed credentials and rotate any affected secrets. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
auto_rollback.py:255
Finding
Snapshot and Rollback Operations Are Not Bound to the Validated Configuration Path<![CDATA[ ## Vulnerability Details **File Location**: `config_modification_v2.py:91-103`, `config_modification_v2.py:136-140`, and `auto_rollback.py:255-263` **Vulnerability Type**: Incorrect rollback target handling and unsafe recovery workflow **Risk Level**: High ### Vulnerable Code The full-cycle command accepts a specific configuration path, but snapshot creation does not pass that path to the backup helper: ```python def cmd_full_cycle(config_path: str) -> int: """完整修改周期: snapshot → intercept → check → verify""" print(f"\n{'='*60}") print(f" 🔒 Config Modification Safety System v2.4") print(f" Powered by halfmoon82 — 知识产权声明") print(f"{'='*60}") print(f"\n配置文件: {config_path}") # Step 1: 创建快照 print("\n[1/4] 📸 创建快照...") import subprocess result = subprocess.run( ["python3", BACKUP_SCRIPT, "snapshot"], capture_output=True, text=True ) ``` Validation failures pass `config_path` into the rollback controller: ```python if summary['failed'] > 0: print("⚠️ 校验失败,触发自动回滚...") controller = AutoRollback() controller.check_and_rollback(results, config_path) print("❌ 修改周期失败") return 1 ``` However, `_execute_rollback()` ignores its `config_path` argument when invoking the external helper: ```python def _execute_rollback(self, config_path: str) -> bool: """执行回滚""" print(f"\n🔄 正在执行自动回滚: {config_path}") try: result = subprocess.run( ["python3", str(self.rollback_script), "rollback"], capture_output=True, text=True, timeout=30 ) ``` ### Technical Analysis The CLI accepts arbitrary absolute paths for the `check` and `full-cycle` commands. The selected path is used during validation, but it is not supplied to either the snapshot or rollback subprocess. Consequently, the displayed and validated target is not cryptographically or logically bound to the recovery operation. The external helper must infer ...[truncated 2794 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Canonicalize every target with `Path.resolve()` and enforce that it is beneath an explicitly permitted directory such as `~/.openclaw`. 2. Reject paths containing symlink escapes or paths outside the declared configuration scope. 3. Pass the exact canonical target to both helper operations: ```python ["python3", BACKUP_SCRIPT, "snapshot", canonical_config_path] ["python3", rollback_script, "rollback", canonical_config_path] ``` 4. Update the external rollback helper interface so the target path is mandatory rather than inferred. 5. Bind snapshot metadata to: - Canonical target path. - File identity. - Timestamp. - Content hash. - Last-known-good validation state. 6. Require `has_backup` to be true before the rollback phase passes. 7. Verify that the selected snapshot contains the exact requested target before invoking rollback. 8. Create snapshots before modification, or maintain a separately marked last-known-good snapshot. Do not treat a post-change snapshot as a safe recovery point. 9. After rollback, verify: - The intended target changed. - Its content hash matches the selected snapshot. - JSON and schema checks pass. - The local gateway is healthy. 10. Make rollback failures fail closed and provide explicit recovery instructions rather than silently continuing. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
config-fswatch-guard.py:86
Finding
Persistent Configuration Watcher Fails Open When Security Validation Cannot Run<![CDATA[ ## Vulnerability Details **File Location**: `config-fswatch-guard.py:86-89` **Vulnerability Type**: Fail-open security validation bypass **Risk Level**: High ### Vulnerable Code ```python except Exception as e: log(f"⚠️ config-modification 调用失败: {e}") log(" 回退到简单 JSON 校验...") return True # 让原逻辑继续 ``` The caller treats this return value as successful validation: ```python # Level 2: config-modification 四联校验 if not run_config_modification_check(): return # 校验失败,已回滚,不再继续 log("📌 fswatch 触发 → 重置健康检查计数器") ``` ### Technical Analysis `run_config_modification_check()` dynamically modifies `sys.path`, imports the validation and rollback modules, runs all validation phases, and potentially performs rollback. Any exception during these operations is caught by a broad `except Exception` handler. The exception handler returns `True`, which has the same meaning as successful completion of all four checks. As a result, failures involving imports, snapshots, permissions, malformed snapshot contents, module defects, filesystem errors, or unexpected runtime conditions downgrade the protection to JSON syntax checking without stopping the workflow. This behavior contradicts the documented claim that all configuration modifications must undergo the complete process without exceptions. It also produces misleading downstream behavior because the health-state counter is reset after the failed security check. A security control must distinguish between: - A configuration that passed validation. - A configuration that failed validation. - A validation system that was unable to reach a conclusion. The implementation incorrectly treats the third state as the first. ### Attack Path 1. The persistent watcher is running and monitoring `~/.openclaw/openclaw.json`. 2. The validation environment becomes unavailable or raises an exception. Examples include: - The Skill directory or module is missing. - Importing `quad_check` or `auto_rollback` fai ...[truncated 1342 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Fail closed when the complete validation system cannot run: ```python except Exception as e: log(f"Validation infrastructure failure: {e}") return False ``` 2. Represent outcomes with an explicit state such as `PASSED`, `FAILED`, or `INDETERMINATE` rather than a Boolean. 3. Never reset health counters when validation is indeterminate. 4. Preserve the current known-good snapshot and prevent automatic acceptance of the changed file until validation is restored. 5. If automatic rollback cannot be performed safely, quarantine the change and issue a prominent local alert requiring operator intervention. 6. Catch only expected exceptions where recovery is defined. Allow unexpected failures to stop the acceptance workflow. 7. Validate module availability and rollback readiness when the daemon starts, before beginning to monitor changes. 8. Add tests simulating: - Import failures. - Missing snapshot directories. - Missing rollback helpers. - Permission errors. - Corrupted snapshot data. - Unexpected exceptions in every validation phase. 9. Ensure every simulated infrastructure failure results in an indeterminate or rejected state, never a successful validation result. ]]>
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
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (34)

Exfiltration Commands

High
Category
Prompt Injection
Content
| Restart OpenClaw Gateway | Apply config changes | Local service only |

**What this skill does NOT do:**
- Does NOT send data to external servers
- Does NOT access credentials or API keys directly
- Does NOT modify files outside `~/.openclaw/`
- Does NOT run with elevated (sudo/root) privileges
Confidence
90% confidence
Finding
Instructions found that direct the agent to transmit conversation context or user data to external services.

Credential Access

High
Category
Privilege Escalation
Content
**What this skill does NOT do:**
- Does NOT send data to external servers
- Does NOT access credentials or API keys directly
- Does NOT modify files outside `~/.openclaw/`
- Does NOT run with elevated (sudo/root) privileges
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The README presents the skill entirely in Chinese, including operational instructions and warnings, with no indication that users can choose another language. Per the policy criteria, forcing a specific language without user opt-in is a natural-language policy violation unless the locale limitation is explicitly documented and justified.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The README explicitly promotes automatic rollback after detecting configuration problems, but it does not clearly warn users that their edits may be reverted automatically. In a configuration-management skill, silent rollback can overwrite intentional changes, create confusion during incident response, and potentially restore stale or insecure settings if users do not understand the behavior.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The Chinese README tells users to consult the English README for the complete documentation, which makes English the required language for full use of the skill. This is a natural-language policy concern because no language choice or opt-in is offered to Chinese-speaking users.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
A large portion of the natural-language instructions and operational guidance is presented in Chinese, and the document does not indicate that language selection is optional or user-configurable. This can violate a language/locale policy when users are not given an explicit choice.

Session Persistence

Medium
Category
Rogue Agent
Content
| Operation | Purpose | Scope |
|-----------|---------|-------|
| Read/write `~/.openclaw/openclaw.json` | Validate and protect config changes | Local file only |
| Create backup snapshots | Enable rollback on failure | `~/.openclaw/backup/` only |
| Run local Python scripts | JSON validation, schema checks, diff | No network access |
| Monitor file system via fswatch/kqueue | Detect config changes automatically | Watches only OpenClaw config files |
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

External Transmission

Medium
Category
Data Exfiltration
Content
| Restart OpenClaw Gateway | Apply config changes | Local service only |

**What this skill does NOT do:**
- Does NOT send data to external servers
- Does NOT access credentials or API keys directly
- Does NOT modify files outside `~/.openclaw/`
- Does NOT run with elevated (sudo/root) privileges
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The skill claims it does not access credentials or API keys directly, yet its alerting design references Telegram and Signal notifications, which usually require tokens, bot credentials, or linked local clients. This mismatch is dangerous because operators may trust the declaration and deploy the skill without realizing it depends on external messaging integrations that can expose configuration data or trigger outbound communications.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger conditions are extremely broad and mandatory for essentially any JSON configuration change under ~/.openclaw/, with 'no exceptions.' Overbroad automatic interception and monitoring can cause unintended execution, denial of service to legitimate workflows, or repeated rollback behavior when unrelated files change.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The module docstring is entirely in Chinese, including the title, usage guidance, and operational descriptions. This imposes a specific language on users without any visible opt-in, alternative locale, or justification that the skill is region-specific.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger list is broad enough to match many ordinary configuration-related requests, which can cause this skill to activate outside its intended scope. Because the skill appears to perform config modification and rollback actions, overbroad routing increases the chance of unintended execution on sensitive configuration tasks.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The rollback API accepts a config_path argument, but _execute_rollback ignores it and always invokes the rollback helper with only a generic 'rollback' command. This can cause the system to roll back the wrong target or a global/default configuration instead of the failed one, creating integrity and availability issues during incident handling.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
print(f"\n🔄 正在执行自动回滚: {config_path}")
        
        try:
            result = subprocess.run(
                ["python3", str(self.rollback_script), "rollback"],
                capture_output=True,
                text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Vague Triggers

Medium
Confidence
93% confidence
Finding
This manifest says the skill 'automatically monitors file changes' and that 'file changes automatically trigger the full process,' but it does not specify which files, directories, or contexts are in scope. Without explicit constraints or exclusion conditions, the trigger condition is ambiguous and could lead to unintended invocation on routine edits.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The top-level documentation says the watcher does three things on config change: validate JSON, roll back on syntax error, and reset a health-check counter. In reality, the implementation additionally loads another skill from disk for "four-check" validation, may trigger automatic rollback based on those results, and explicitly restarts the Gateway after rollback on JSON errors, which materially expands the behavior beyond the stated intent.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The module docstring and operational log messages are written in Chinese, which establishes a fixed language for user-visible behavior. Under the stated policy, forcing a specific language without offering user choice or documenting a justified locale restriction is a natural-language policy violation.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# 立即回滚
        _self_writing = True
        try:
            result = subprocess.run(
                ["python3", ROLLBACK_SCRIPT, "rollback"],
                capture_output=True, text=True, timeout=10
            )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
os.path.expanduser("~/.local/share/fnm/node-versions/v24.13.0/installation/bin/openclaw")
        )
        try:
            result = subprocess.run(
                [openclaw_bin, "gateway", "restart"],
                capture_output=True, text=True, timeout=30
            )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This code presents its primary description, usage instructions, status messages, and errors in Chinese, which imposes a specific language on users. There is no opt-in, alternate locale, or explanation that the skill is intended only for a Chinese-speaking or region-specific environment.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
The documentation claims the tool 'intercepts' configuration modifications, but the implementation only performs checks and possible rollback after actions are already underway or completed. This can create a false sense of enforcement, causing operators or dependent tooling to assume unsafe changes are blocked when they are not, which may allow harmful configuration changes to take effect before detection or rollback.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# Step 1: 创建快照
    print("\n[1/4] 📸 创建快照...")
    import subprocess
    result = subprocess.run(
        ["python3", BACKUP_SCRIPT, "snapshot"],
        capture_output=True, text=True
    )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This Python file presents its module docstring, usage guidance, and operational descriptions entirely in Chinese, which can constitute a language policy violation when no user opt-in or alternative locale is offered. The rule applies to all file types, including code files, when natural-language strings impose a specific language.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The phase docstring describes two checks: gateway reachability and config writability, but line L357 only says '配置文件可写性' as a health criterion without indicating that writability is mandatory for overall health. In practice, the function returns failure solely because the file is not writable, which expands 'health' from service availability into a write-permission gate for the config path.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
            # 1. 检查 Gateway 健康
            try:
                result = subprocess.run(
                    ["curl", "-s", "-o", "/dev/null", "-w", "%{http_code}",
                     "http://127.0.0.1:18789/health"],
                    timeout=5, capture_output=True, text=True
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.