T09 · Insecure Skill Coding Practices
Warning
- Location
- index.js:43
- Finding
- Unfiltered Workspace Source Code Replication into Publishable Bundles## Vulnerability Details **File Location**: `index.js:43-58`, `index.js:122-139`, `index.js:174-177` **Vulnerability Type**: Unfiltered sensitive source-code exposure **Risk Level**: Medium ### Vulnerable Code ```js function scanSkills() { const dirs = fs.readdirSync(WORKSPACE).filter(d => { const stat = fs.statSync(path.join(WORKSPACE, d)); return stat.isDirectory() && !d.startsWith('evomap-'); }); const skills = []; for (const dir of dirs) { const skillPath = path.join(WORKSPACE, dir, 'SKILL.md'); const pkgPath = path.join(WORKSPACE, dir, 'package.json'); if (fs.existsSync(skillPath)) { const skillMd = fs.readFileSync(skillPath, 'utf8'); const name = extractName(skillMd) || dir; const description = extractDesc(skillMd) || ''; const signals = extractSignals(skillMd); let code = ''; const indexPath = path.join(WORKSPACE, dir, 'index.js'); if (fs.existsSync(indexPath)) { code = fs.readFileSync(indexPath, 'utf8').substring(0, 2000); } ``` ```js const codeSnippet = skill.code && skill.code.length > 50 ? skill.code.substring(0, 3000) : null; const capsule = { type: 'Capsule', schema_version: '1.5.0', trigger: signals, gene: '', summary: skill.description || `Capsule for ${skill.displayName} - implements ${category} pattern`, content: generateCapsuleContent(skill), code_snippet: codeSnippet, confidence: 0.95, blast_radius: { files: Math.ceil((skill.code || '').length / 500) || 1, lines: (skill.code || '').split('\n').length || 10 }, outcome: { status: 'success', score: 0.95 }, success_streak: 5, env_fingerprint: { platform: 'linux', arch: 'x64', node_version: 'v22.22.0' } }; ``` ```js fs.writeFileSync( path.join(outputDir, 'bundle_' + skill.name + '.json'), JSON.stringify(bundle) ); ``` ### Technical Analysis The `scanSkills ...[truncated 2687 chars]
- Remediation
- ## Remediation Suggestions 1. Default to metadata-only bundles and require explicit user approval before including source code. 2. Use an allowlist that identifies the exact Skills, files, and line ranges permitted for export. 3. Run secret detection before serialization, covering API keys, bearer tokens, private keys, passwords, connection strings, and high-entropy literals. 4. Redact detected values and fail closed when sensitive content cannot be handled safely. 5. Display the complete proposed `code_snippet` to the user and require confirmation before writing a publishable bundle. 6. Add a Skill-level configuration option that explicitly marks source as safe for publication. 7. Avoid treating declarative `forbidden_paths` metadata as an enforcement mechanism; enforce restrictions during file discovery and content processing. 8. Add automated tests proving that representative credentials and private keys never appear in generated JSON. 9. Document that generated bundles may contain source code and must be reviewed before external distribution. 10. Consider replacing raw source excerpts with reviewed examples, hashes, or references when full implementation content is unnecessary.
