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

Content
View full analysis

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
View 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