Back to skill

Security audit

disk-cleaner

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real disk-cleaning tool, but it needs review because some cleanup paths and defaults can permanently delete unrelated or persistent user data.

Install only if you are comfortable reviewing every selected path before deletion. Prefer --dry-run first, avoid --force, use --no-trash unless you explicitly want the recycle bin emptied, and be cautious with Electron app storage, logs, developer caches, and any symlinked cache directories.

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
scripts/clean_cache.py:284
Finding
Symbolic Link Resolution Causes Deletion of the Link Target<![CDATA[ ## Vulnerability Details **File Location**: `scripts/clean_cache.py`, lines 284–306 and 546–563 **Vulnerability Type**: Unsafe symbolic-link handling leading to arbitrary directory deletion **Risk Level**: High ### Vulnerable Code ```python def assert_safe(path: str) -> str: """删除前最终闸门。 1. 用 os.path.realpath 解析符号链接 / junctions,得到真实路径; 2. 真实路径必须严格位于某个允许根区之下(边界安全); 3. 命中系统关键片段(FORBIDDEN_PARTS)一律拒绝; 4. 拒绝驱动器根目录。 返回解析后的真实路径(供后续删除使用)。 """ try: real = os.path.realpath(os.path.abspath(path)) except Exception: real = os.path.abspath(path) real_norm = real.rstrip(os.sep).lower() if len(real_norm) == 2 and real_norm[1] == ":": raise RuntimeError(f"拒绝删除驱动器根目录: {real}") low = real.lower() for bad in FORBIDDEN_PARTS: if bad in low: raise RuntimeError(f"禁止删除系统关键路径: {real}") if not any(_is_under(real_norm, r) for r in _allowed_roots_norm()): raise RuntimeError(f"拒绝删除白名单外的路径: {real}") return real ``` The resolved path is subsequently stored in the deletion plan: ```python def collect(items, min_bytes): """计算大小并过滤,返回 (可选计划, 被拒绝项, 被占用跳过项)。""" plan, rejected, busy = [], [], [] for it in items: try: safe = assert_safe(it["path"]) except RuntimeError as e: rejected.append((it["name"], str(e))) continue if it.get("guard") and process_running(it["guard"]): busy.append(it["name"]) continue size = dir_size(safe) if size < min_bytes: continue it = dict(it) it["path"], it["size"] = safe, size plan.append(it) ``` ### Technical Analysis The deletion safety design claims that symbolic links and junctions are removed without recursively following their targets. However, `assert_safe()` resolves the selected path through `os.path.realpath()` and returns the resolved target rather than the original link path. `collect()` ...[truncated 1867 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not return the resolved target from `assert_safe()`. Preserve and return the original absolute path after validation. - Reject top-level symbolic links and junctions, or explicitly remove only the link itself. - Validate the original lexical path and its resolved parent separately: - Confirm the original path is under an approved cache root. - Resolve and validate the parent directory. - Use `lstat()` to identify the final component without following it. - On Windows, explicitly detect reparse points and junctions instead of relying only on `os.path.islink()`. - Narrow `ALLOWED_ROOTS`; do not treat the entire user home directory as an unrestricted deletion root. - Re-run safety validation immediately before deletion to reduce time-of-check/time-of-use race exposure. - Add automated tests for: - A cache path that is a symbolic link to a project directory. - Nested symbolic links. - Windows junctions and reparse points. - Links replaced between planning and deletion. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/clean_cache.py:399
Finding
Persistent Electron Application Data Is Misclassified as Regenerable Cache<![CDATA[ ## Vulnerability Details **File Location**: `scripts/clean_cache.py`, lines 399–402 and 448–458 **Vulnerability Type**: Unsafe deletion classification causing application data loss **Risk Level**: High ### Vulnerable Code ```python # Electron 系应用缓存子目录(VS Code / Trae / Cursor 等) ELECTRON_SUBDIRS = [ "CachedData", "Cache", "Code Cache", "logs", "Crashpad", "WebStorage", "Partitions", "ModularData", "CachedExtensionVSIXs", "GPUCache", "Local Storage", "Session Storage", "blob_storage", ] ``` Every matching directory is classified as GREEN: ```python for pattern, plats in ELECTRON_SCAN: if not platform_ok(plats): continue for base in expand(pattern): for sub in ELECTRON_SUBDIRS: p = os.path.join(base, sub) if os.path.isdir(p): items.append({"name": f"应用缓存[{os.path.basename(base)}/{sub}]", "path": p, "tier": TIER_GREEN, "guard": None, "source": "whitelist"}) ``` ### Technical Analysis The code treats every directory listed in `ELECTRON_SUBDIRS` as a regenerable GREEN cache. Several listed names are not universally cache-only locations: - `Local Storage` - `Session Storage` - `WebStorage` - `Partitions` - `ModularData` - `blob_storage` Electron applications may use these directories for persistent web application state, authentication sessions, IndexedDB or related databases, extension state, partition-specific profiles, and locally stored user content. Their semantics depend on the application and cannot safely be inferred solely from the directory name. Because these entries are marked GREEN and sourced from the whitelist, the `g` selection mode includes them automatically. This conflicts with the stated policy that only regenerable caches are deleted. ### Attack Path 1. A supported Electron application stores persistent state in one of the listed directories. 2. The cleaner scans the application's data director ...[truncated 1048 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove persistent-storage locations such as `Local Storage`, `Session Storage`, `WebStorage`, `Partitions`, `ModularData`, and `blob_storage` from the generic GREEN list. - Restrict GREEN classification to application-documented cache-only paths, such as `Cache`, `Code Cache`, and `GPUCache`. - Maintain application-specific allowlists rather than applying one generic Electron directory list to all applications. - Classify uncertain locations as `DISCOVERED` or a higher-risk tier that cannot be selected through the `g` shortcut. - Display a specific warning when a directory may contain sessions, databases, or unsynchronized state. - Require applications to be closed before deleting their cache directories to prevent corruption and recreation races. - Add integration tests using representative Electron profile layouts to verify that persistent storage is never included in GREEN cleanup. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/clean_cache.py:725
Finding
Recycle Bin Contents Are Permanently Deleted Without Separate Selection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/clean_cache.py`, lines 529–543 and 725–726 **Vulnerability Type**: Unconfirmed destructive operation **Risk Level**: Medium ### Vulnerable Code ```python def empty_trash() -> str: if os.name == "nt": try: import ctypes flags = 0x00000001 | 0x00000002 | 0x00000004 ctypes.windll.shell32.SHEmptyRecycleBinW(None, None, flags) return "已清空回收站" except Exception: return "回收站清空失败" trash = os.path.join(HOME, ".local/share/Trash") if PLATFORM == "linux" \ else os.path.join(HOME, ".Trash") if os.path.isdir(trash): remove_tree(trash) return "已清空回收站" return "跳过(未找到回收站目录)" ``` The operation is automatically performed after cleaning any selected item: ```python if not args.no_trash: print(f" [..] {empty_trash()}") ``` ### Technical Analysis The recycle bin is emptied by default after any selected cleanup unless the user supplies `--no-trash`. Its contents are not represented as a separate plan item and are not included in the item-by-item selection, detailed confirmation display, or estimated deletion total. Consequently, confirming deletion of a cache item also authorizes a separate and materially different destructive operation that permanently removes unrelated files from the recycle bin. This violates the documented two-stage, per-item confirmation model. On Windows, `SHEmptyRecycleBinW` empties the recycle bin without displaying confirmation or progress UI because of the selected flags. On Linux and macOS, the implementation recursively deletes the corresponding trash directory. ### Attack Path 1. The user has unrelated files in the recycle bin that remain recoverable. 2. The user runs the cleaner and selects one or more cache items. 3. The confirmation screen describes only the selected cleanup entries. 4. The user confirms those entries. 5. After processing them, the program calls ...[truncated 634 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Preserve the recycle bin by default. - Replace the negative `--no-trash` option with an explicit opt-in option such as `--empty-trash`. - Add the recycle bin as a separate plan item with its path, measured size, risk classification, and deletion consequences. - Require explicit selection and confirmation before permanently emptying it. - Exclude recycle-bin deletion from bulk GREEN selection unless the user specifically requests it. - Clearly state that this operation is permanent and affects files unrelated to the selected caches. - On supported platforms, prefer native APIs that can report failures accurately and avoid deleting the trash root directory itself. ]]>
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (9)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill advertises and instructs shell, environment, and file access behavior but does not declare any explicit tool scope or permissions boundary. In a destructive workflow like disk cleanup, missing scope declarations increases the chance an agent can invoke broader-than-necessary capabilities or operate without transparent authorization, which is especially risky because the documented behavior includes file deletion and trash emptying.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The manifest description is entirely in Chinese and specifies usage triggers in Chinese only, which indicates a language-specific invocation policy. There is no indication that the skill supports other languages, offers user opt-in, or is intentionally limited to a Chinese-only compliance or regional context.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
try:
        import subprocess
        if os.name == "nt":
            out = subprocess.run(["tasklist"], capture_output=True, text=True,
                                 errors="ignore").stdout.lower()
        else:
            out = subprocess.run(["ps", "-eo", "comm="], capture_output=True, text=True,
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
out = subprocess.run(["tasklist"], capture_output=True, text=True,
                                 errors="ignore").stdout.lower()
        else:
            out = subprocess.run(["ps", "-eo", "comm="], capture_output=True, text=True,
                                 errors="ignore").stdout.lower()
        return any(n.lower() in out for n in names)
    except Exception:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The whitelist includes cleanup of user home-directory logs and tracing data for the tool itself, which exceeds the manifest's stated cache-cleaning scope. Deleting logs/traces can erase forensic, debugging, or audit data and may surprise users who consented only to cache cleanup.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The tool treats developer artifacts and local repositories such as Maven, Gradle, Xcode archives, simulators, and model/browser caches as cleanup targets, even though many are not mere transient caches. In a disk-cleaner skill this is more dangerous because users may approve deletion expecting only low-risk cache removal, but these paths can cause significant rebuild/download costs and loss of valuable local artifacts.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The skill empties the system recycle bin/trash after cleanup, which is broader and more destructive than cache removal. This can permanently remove user-recoverable files unrelated to the requested task, increasing the chance of unexpected data loss, especially because users may reasonably interpret the tool as affecting only caches and temp files.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
This markdown file contains user-facing instructions and descriptions only in Chinese, which can amount to a language/locale policy violation when no user opt-in or alternative language is provided. The file does not indicate that the skill is region-specific or that Chinese is an explicit requirement.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The file is written entirely in Chinese and does not indicate that language selection is optional or user-configurable. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation unless explicitly justified.

Static analysis

No suspicious patterns detected.