T09 · Insecure Skill Coding Practices
- Location
scripts/parse-chatgpt-export.js:31- Finding
Shell Command Injection Through an Attacker-Controlled ZIP Path
- Content
View full analysis
'); console.error('Parses a ChatGPT data export ZIP and outputs structured JSON.'); process.exit(zipPath === '--help' ? 0 : 1); } if (!fs.existsSync(zipPath)) { console.error(`File not found: ${zipPath}`); process.exit(1); } const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chatgpt-export-')); try { // Extract ZIP with path traversal protection execSync(`unzip -o -q "${zipPath}" -d "${tmpDir}"`, { stdio: 'pipe' }); ``` ### Technical Analysis The ZIP path is accepted directly from `process.argv[2]` and interpolated into a command string passed to `execSync`. By default, `execSync` executes the string through a system shell. Surrounding the path with double quotes is not sufficient shell escaping. A path containing a double quote, command substitution, or other shell syntax can terminate or alter the intended argument and cause the shell to execute additional commands. The preceding `fs.existsSync(zipPath)` check does not sanitize the path and does not prevent exploitation if a file with a crafted name exists. The parser is explicitly invoked on user-uploaded ZIP files, so the filename or path may be attacker-controlled. Calling an external extractor is reasonable for the declared function, but invoking it through a shell is unnecessary and exceeds the minimum risk needed for extraction. ### Attack Path 1. An attacker creates a valid ZIP file whose local filename or supplied path contains shell-significant characters. 2. The file is uploaded for ChatGPT memory migration. 3. The Agent invokes the documented parser with the uploaded path. 4. The parser interpolates that path into the `unzip` shell command. 5. The shell ...[truncated 752 chars]- Remediation
View remediation
