T09 · Insecure Skill Coding Practices
Warning
- Location
- src/interchange.js:94
- Finding
- Raw Task Telemetry Is Published in a Shareable Operations Report<![CDATA[ ## Vulnerability Details **File Location**: `src/interchange.js:94-103` **Vulnerability Type**: Sensitive information exposure across a documented trust boundary **Risk Level**: Medium ### Vulnerable Code ```js const content = `# System Health ${overallIcon} **Overall:** ${taskHealthy && cronHealthy ? 'Healthy' : 'Degraded'} ## Subsystems - ${taskIcon} **Tasks:** ${taskTotal === 0 ? 'No activity today' : taskHealthy ? 'Healthy' : 'Failures detected'} - ${cronIcon} **Crons:** ${status.cron_ok + status.cron_fail === 0 ? 'No runs today' : cronHealthy ? 'All passing' : 'Failures detected'} - ${hasActivity ? '🟢' : '⚪'} **Token Collection:** ${hasActivity ? 'Active' : 'No data today'} ## Recent Errors ${status.recent_errors.length === 0 ? 'None' : status.recent_errors.map(e => `- ${e.command}: ${e.error || 'unknown error'}`).join('\n')} `; await writeMd(path.join(INTERCHANGE_DIR, 'ops', 'health.md'), meta, content); ``` The underlying values are selected without redaction in `src/reports.js:48-50`: ```js const recentErrors = db.prepare(` SELECT command, error, timestamp FROM task_events WHERE status != 'success' AND timestamp > datetime('now', '-7 days') ORDER BY timestamp DESC LIMIT 5 `).all(); ``` ### Technical Analysis The Skill documentation states that `interchange/monitoring/ops/health.md` is shareable and contains status indicators only, while detailed information is reserved for the private `state` layer. The implementation violates this boundary by publishing raw task command and error strings in the operations-layer report. Task commands and errors commonly contain file paths, user identifiers, request fragments, prompts, infrastructure names, exception details, or accidentally logged credentials. Neither the collector nor the report generator redacts these values before writing them to the shareable file. Although no network transmission is implemented, the README explicitly describes interchange reports as available for ...[truncated 1378 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove raw `command` and `error` values from `ops/health.md`; expose only aggregate indicators such as the number of recent failures. 2. Keep diagnostic details exclusively in the private `state` layer. 3. Apply centralized redaction for credentials, authorization headers, tokens, URLs containing secrets, email addresses, and sensitive paths. 4. Truncate diagnostic fields to a conservative maximum length. 5. Define and enforce an explicit schema for data permitted in each interchange layer. 6. Set restrictive filesystem permissions on private state reports and document the expected access-control model. 7. Add tests proving that distinctive command and error values never appear in operations-layer files. ]]>
