T09 · Insecure Skill Coding Practices
- Location
index.js:52- Finding
OS Command Injection Through User-Controlled Repository URL and Token
- Content
View full analysis
{ // 创建临时目录测试访问 const tempDir = path.join('/tmp', 'test_git_access_' + Date.now()); exec(`git clone ${repoUrl.replace('https://', `https://${token}@`)} ${tempDir}`, (error, stdout, stderr) => { if (error) { console.error('仓库访问验证失败:', error.message); resolve(false); } else { console.log('仓库访问验证成功'); // 清理临时目录 exec(`rm -rf ${tempDir}`); resolve(true); } }); }); } ``` ```javascript async setupGithubRepo(repoUrl) { const repoName = repoUrl.split('/').pop().replace('.git', ''); this.githubRepoPath = path.join(process.env.HOME || '.', 'Documents', 'GitHub', repoName); // 检查仓库是否已存在 if (!fs.existsSync(this.githubRepoPath)) { console.log(`克隆仓库到: ${this.githubRepoPath}`); await this.executeCommand(`git clone ${repoUrl} "${this.githubRepoPath}"`); } else { console.log(`仓库已存在,更新仓库: ${this.githubRepoPath}`); await this.executeCommand(`cd "${this.githubRepoPath}" && git pull origin main`); } } ``` ### Technical Analysis Both `repoUrl` and `token` originate from user input and are interpolated directly into strings passed to `child_process.exec()`. The `exec()` function invokes a system shell, so shell metacharacters embedded in either value are interpreted as command syntax rather than as literal Git arguments. Quoting only `this.githubRepoPath` does not protect the unquoted `repoUrl`. The token is also inserted into the URL without shell escaping. URL parsing with `split()` and `replace()` does not constitute input validation and does not prevent shell injection. ### Attack Path 1. An attacker persuades a user or automation system to configure the Skill with ...[truncated 986 chars]- Remediation
View remediation
