Back to skill

Security audit

Risk Guard

Security checks for vulnerabilities and agentic risk

Overview

The skill is mainly a local OpenClaw diagnostic helper, but it automatically deletes workspace .lock and .tmp files even though it presents deletion as requiring confirmation.

Review before installing. Use --dry-run for diagnostics unless you explicitly want cleanup, and do not run the script in a workspace where older .lock or .tmp files might still be important. The skill should be changed so cleanup is a separate explicit action with a listed confirmation step.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/diagnose.py:148
Finding
Automatic Deletion of Workspace Files Without Confirmation or Sufficient Validation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/diagnose.py`, lines 148-170 **Vulnerability Type**: Unsafe automatic file deletion **Risk Level**: Medium ### Vulnerable Code ```python def check_lock_files(): """锁文件清理(dry-run模式不删除;直接尝试删除,PermissionError表示被占用)""" if not WORKSPACE: return "skip", "无法确定工作区,跳过" removed = 0 skipped = 0 for f in os.listdir(WORKSPACE): if not (f.endswith(".lock") or f.endswith(".tmp")): continue path = os.path.join(WORKSPACE, f) try: age = datetime.now().timestamp() - os.path.getmtime(path) if age <= 600: continue if not DRY_RUN: os.remove(path) removed += 1 else: removed += 1 # dry-run 计数但不实际删除 except PermissionError: skipped += 1 except Exception: pass ``` ### Technical Analysis The diagnostic script deletes every top-level workspace entry whose name ends in `.lock` or `.tmp` and whose modification time is more than 600 seconds old. Deletion occurs during normal execution because dry-run behavior is opt-in through `--dry-run`. A filename suffix and modification age are insufficient to establish that a file is stale or safe to remove. The implementation does not: - Confirm that the file belongs to this skill or the OpenClaw application. - Validate an expected filename pattern or file contents. - Determine whether a process is still actively using the file. - Require explicit cleanup authorization from the user. - Restrict deletion to a dedicated, application-owned cleanup directory. - Confirm that the selected path represents an expected regular disposable file. This behavior also conflicts with the documented principle that the skill only diagnoses problems and that irreversible deletion requires confirmation. Although the documentation describes this cleanup as safely reversible, `os.remove()` does ...[truncated 1736 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make diagnostic mode strictly read-only by default. Do not delete files unless the user supplies a separate explicit option such as `--cleanup-stale-locks`. 2. Require interactive confirmation immediately before deletion, listing every affected path. For unattended use, require an explicit high-risk acknowledgment flag. 3. Restrict cleanup to a dedicated application-owned lock directory rather than scanning the workspace root. 4. Use an allowlist of exact application-generated filename patterns instead of accepting every `.lock` or `.tmp` suffix. 5. Verify that each candidate is a regular file and belongs to the expected application before deletion. 6. Where lock files contain process identifiers or ownership metadata, validate that the associated process no longer exists and that the metadata matches the current workspace. 7. Replace silent exception handling with structured logging that records the affected path, operation, and error without exposing sensitive file contents. 8. Consider moving candidates to an application-controlled quarantine or recycle location first, allowing recovery before permanent deletion. 9. Update `SKILL.md` to state accurately that file deletion is irreversible and requires prior approval under the documented risk model. 10. Refactor the interface so cleanup is separate from diagnostics, for example: ```python parser.add_argument( "--cleanup-stale-locks", action="store_true", help="Explicitly request cleanup of validated application-owned stale lock files", ) if not args.cleanup_stale_locks: return "info", "Cleanup not requested; diagnostic scan only" ``` ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (15)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documented purpose says the skill only diagnoses and requires confirmation before irreversible actions, yet the content explicitly allows automatic cleanup of `.lock` and `.tmp` files and does not show an enforceable confirmation mechanism. This mismatch is dangerous because operators may trust the skill as read-only while it performs deletions or other operational side effects without a guaranteed approval gate.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The header comments explicitly claim lock-file deletion requires confirmation, but check_lock_files deletes eligible files automatically unless --dry-run is set. This mismatch is dangerous because operators may trust the documented safety guarantees and run the script expecting non-destructive behavior, leading to unintended file removal.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
try:
        encoded = base64.b64encode(cmd.encode("utf-16-le")).decode()
        full_cmd = f'powershell.exe -NoProfile -NonInteractive -EncodedCommand {encoded}'
        result = subprocess.run(
            full_cmd, shell=True, capture_output=True,
            text=True, timeout=timeout,
            encoding="utf-8", errors="replace"
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
def run_cmd(cmd, timeout=10):
    """执行普通命令"""
    try:
        result = subprocess.run(
            cmd, shell=True, capture_output=True,
            text=True, timeout=timeout,
            encoding="utf-8", errors="replace"
Confidence
90% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises operational behavior that involves shell execution, file access, environment access, and likely network checks, but it declares no explicit tool scope or permission boundaries. In an agent environment, missing least-privilege declarations can cause the skill to run with broader capabilities than intended, increasing the blast radius if the skill is triggered unexpectedly or later expanded.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger phrase `诊断` is broad enough to match ordinary user requests, which can cause the skill to activate outside its intended context. When a skill has shell and file-handling behavior, ambiguous activation increases the chance of unplanned execution of diagnostic commands or cleanup logic.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The trigger section describes activation in loose terms without clear boundaries, making it easier for normal conversational requests to invoke the skill. In a skill that can inspect processes, ports, paths, and potentially remove files, ambiguous activation raises the risk of unintended execution and user surprise.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The file’s banner, CLI description, status messages, and operator instructions are written exclusively in Chinese, indicating the skill is designed to communicate in a single language by default. The file does not offer any language selection, fallback, or justification that this is a region-specific tool, which makes it a natural-language locale policy issue under the stated rules.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
        encoded = base64.b64encode(cmd.encode("utf-16-le")).decode()
        full_cmd = f'powershell.exe -NoProfile -NonInteractive -EncodedCommand {encoded}'
        result = subprocess.run(
            full_cmd, shell=True, capture_output=True,
            text=True, timeout=timeout,
            encoding="utf-8", errors="replace"
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
def run_cmd(cmd, timeout=10):
    """执行普通命令"""
    try:
        result = subprocess.run(
            cmd, shell=True, capture_output=True,
            text=True, timeout=timeout,
            encoding="utf-8", errors="replace"
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Description-Behavior Mismatch

Medium
Confidence
97% confidence
Finding
The skill is presented as a diagnostic and risk-confirmation tool, yet it automatically deletes .lock and .tmp files older than 10 minutes during normal execution. That creates an integrity risk because a user invoking self-check may trigger destructive changes without explicit consent, and those files may still be operationally significant despite age-based heuristics.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The description is written to address the user as "先生" and presents the skill behavior entirely in Chinese without indicating that language selection is optional. This can be a natural-language policy issue because it implicitly forces a specific language/locale and form of address without user opt-in.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
The description consistently instructs interactions using the specific honorific/register "先生掌控" and frames confirmations as addressed to "先生". This imposes a language style on users without any opt-in or documented justification, which can violate language/locale neutrality expectations.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The confirmation prompt addresses the user as "先生" and requires the interaction in that register. Because no opt-in or user preference mechanism is described, this is a natural-language policy concern related to forced language/style.

Vague Triggers

Low
Confidence
82% confidence
Finding
The manifest lists activation phrases as "自检、诊断、风险确认" without clarifying context, exclusions, or when the skill should not activate. Terms like "自检" and especially "诊断" can occur in ordinary troubleshooting conversations, which may cause unintended invocation.

Static analysis

No suspicious patterns detected.