T09 · Insecure Skill Coding Practices
- Location
scripts/task_io.mjs:36- Finding
Unrestricted File Modification Through User-Controlled Task Path
- Content
View full analysis
c.url === url); if (!cand) throw new Error(`Candidate not found for url: ${url}`); cand.status = status; await fs.writeFile(file, JSON.stringify(raw, null, 2) + '\n', 'utf8'); return raw; } ``` The vulnerable function is directly exposed through the command-line interface: ```js } else if (cmd === 'status') { const file = arg('file'); const url = arg('url'); const status = arg('status'); if (!file || !url || !status) throw new Error('Need --file --url --status'); await updateCandidateStatus(file, url, status); console.log('OK'); } ``` ### Technical Analysis The `updateCandidateStatus` and `finalizeTask` functions accept a caller-controlled `file` path and pass it directly to `fs.readFile` and `fs.writeFile`. The path is not resolved against the intended artifact directory, canonicalized, or checked to ensure that it remains under: ```text /home/miles/.openclaw/workspace/artifacts/secure_shopping ``` Consequently, absolute paths, directory-traversal paths, and paths involving symbolic links are not rejected. The command-line `status` operation exposes this behavior through its `--file` option. Successful modification requires the target to be valid JSON with the expected structure, including a `task.candidates` array con ...[truncated 2057 chars]- Remediation
View remediation
