Back to skill

Security audit

File Cleaner

Security checks for vulnerabilities and agentic risk

Overview

This file-cleaning skill is purpose-aligned but its safety check can allow unintended recursive deletion outside the directories it claims to restrict itself to.

Review before installing or using this skill. It should not be used on workspaces with important sibling paths whose names begin with temp, logs, or cache until the path containment check is fixed to use path-component-aware validation.

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

Error
Location
index.js:18
Finding
Path Prefix Validation Allows Out-of-Scope Recursive Deletion## Vulnerability Details **File Location**: `index.js`, lines 18-25; deletion sink at lines 38-46 **Vulnerability Type**: Improper path containment validation **Risk Level**: High ### Vulnerable Code ```js const allowedPrefixes = [ path.join(workspaceRoot, 'temp'), path.join(workspaceRoot, 'logs'), path.join(workspaceRoot, 'cache') ]; const isAllowed = allowedPrefixes.some(prefix => absolutePath.startsWith(prefix)); if (!isAllowed) { // Also allow specific single files if they are clearly temp files in root (e.g. *.tmp, *.log) // But generally enforce temp/ usage. // For now, strict safety: only allow deletion inside temp/, logs/, or cache/ throw new Error(`Safety Warning: Deletion denied for path '${targetPath}'. Only paths inside 'temp/', 'logs/', or 'cache/' are allowed.`); } if (absolutePath === workspaceRoot || absolutePath === path.join(workspaceRoot, 'skills')) { throw new Error('CRITICAL: Attempted to delete workspace root or skills directory.'); } try { const stats = await fs.promises.stat(absolutePath); if (stats.isDirectory()) { await fs.promises.rm(absolutePath, { recursive: true, force: true }); return `Successfully deleted directory: ${targetPath}`; } else { await fs.promises.unlink(absolutePath); return `Successfully deleted file: ${targetPath}`; } ``` ### Technical Analysis The implementation uses `String.prototype.startsWith()` to determine whether a resolved path is within one of the permitted directories. This checks only the textual prefix and does not enforce a filesystem path-component boundary. Consequently, sibling paths such as `temperature`, `logs-backup`, and `cache-secrets` are incorrectly accepted because their absolute path strings begin with the strings for `temp`, `logs`, or `cache`. Traversal input can produce the same result: for example, `temp/../temperature` resolves to the sibling directory `temperature`, after ...[truncated 1703 chars]
Remediation
## Remediation Suggestions Replace textual prefix checks with path-component-aware containment validation. For example: ```js function isWithinOrEqual(parent, candidate) { const relative = path.relative(parent, candidate); return relative === '' || (relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative)); } const isAllowed = allowedPrefixes.some(prefix => isWithinOrEqual(prefix, absolutePath) ); ``` If deleting `temp/`, `logs/`, or `cache/` themselves is not required, reject `relative === ''` and permit descendants only. Additional hardening should include: 1. Resolve the workspace root once from an explicitly trusted configuration rather than implicitly relying on the caller's current working directory. 2. Define whether symbolic links are permitted. If not, inspect path components with `lstat()` and reject symlinked components before deletion. 3. Minimize time-of-check/time-of-use exposure where feasible, especially if untrusted users can modify workspace paths concurrently. 4. Add automated negative tests for `temperature`, `logs-backup`, `cache-secrets`, `temp/../temperature`, absolute out-of-scope paths, and other prefix collisions. 5. Add positive tests confirming that genuine descendants such as `temp/session/file.tmp` remain permitted. 6. Test whether deletion of the three allowed root directories should be explicitly prohibited.
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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep