T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/run-task.js:367
- Finding
- Dry-run mode performs unintended filesystem writes<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run-task.js:219-229`, `scripts/run-task.js:367-390` **Vulnerability Type**: Dry-run safety violation and unsafe file creation **Risk Level**: Medium ### Vulnerable Code ```js function resolveWorkingPsdPath(task, sourcePath) { const sourceMode = task.workflow?.sourceMode || "inplace"; if (sourceMode !== "copy_then_edit") { return { sourceMode, workingPath: sourcePath, copiedFrom: undefined }; } const copyToDir = path.resolve(expandHome(task.workflow?.copyToDir || resolveDesktopDir())); const fileName = path.basename(sourcePath); const workingPath = path.join(copyToDir, fileName); ensureParentDir(workingPath); fs.copyFileSync(sourcePath, workingPath); return { sourceMode, workingPath, copiedFrom: sourcePath }; } ``` The filesystem-mutating function is invoked before the dry-run condition is evaluated: ```js const platform = os.platform(); const dryRun = Boolean(args.dryRun || (normalizedTask.options && normalizedTask.options.dryRun)); const workingInfo = resolveWorkingPsdPath(normalizedTask, resolved.path); const pathBridge = platform === "darwin" ? prepareMacPathBridgeIfNeeded(normalizedTask, workingInfo.workingPath) : { executionPath: workingInfo.workingPath, syncBack: () => {} }; const edits = normalizedTask.input.edits || []; const plannedExports = Array.isArray(normalizedTask.output?.exports) ? normalizedTask.output.exports : []; const matchImagePath = normalizedTask.options?.matchImagePath ? path.resolve(expandHome(normalizedTask.options.matchImagePath)) : ""; const enableBundleZip = normalizedTask.options?.bundleZip === true; const plannedPngPaths = plannedExports .filter((item) => item.format === "png") .map((item) => item.mode === "layer_sets" ? resolvePngOutputDir(item, workingInfo.workingPath) : resolvePngOutputPath(item, workingInfo.workingPath), ); if (dryRun) { ``` ### Technical Analysis A dry-run is expected to calcula ...[truncated 2170 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Evaluate dry-run mode immediately after task validation and path resolution, before invoking any function that creates directories, copies files, writes logs, or prepares temporary files. 2. Split path planning from path execution: - Add a pure function that calculates the intended working and bridge paths. - Only create directories and copy files in the real execution branch. 3. Do not call `resolveWorkingPsdPath()` or `prepareMacPathBridgeIfNeeded()` during dry-run unless they support an explicit non-mutating mode. 4. Before copying during actual execution, detect an existing destination and require an explicit overwrite option or generate a collision-resistant filename. 5. Add automated tests that snapshot the relevant filesystem before and after dry-run and assert that no files or directories are created, modified, or overwritten. 6. Consider whether writing the audit log during dry-run is intended. If strict zero-mutation semantics are required, return the preview without appending to a persistent log or explicitly document that exception. ]]>
