T09 · Insecure Skill Coding Practices
Error
- Location
- progress-tracker.js:360
- Finding
- Stored HTML Injection in Generated Progress Reports<![CDATA[ ## Vulnerability Details **File Location**: `progress-tracker.js`, lines 360-365 **Vulnerability Type**: Stored HTML injection / cross-site scripting **Risk Level**: High ### Vulnerable Code ```javascript ${summary.tasks.map(task => ` <tr> <td>${task.name}</td> <td>${task.status}</td> <td>${task.progress}%</td> <td>${task.assignedAgent}</td> </tr> `).join('')} ``` ### Technical Analysis The HTML report generator directly interpolates task-controlled values into HTML markup without context-appropriate encoding. The affected fields include: - `task.name` - `task.status` - `task.progress` - `task.assignedAgent` These values can originate from task and agent metadata supplied to the progress tracker. Because characters such as `<`, `>`, `"`, `'`, and `&` are not escaped, an attacker can provide HTML containing executable event handlers or other active content. For example, a malicious task name could contain: ```html <img src="x" onerror="alert(document.domain)"> ``` When `generateProgressReport('html')` renders the report, this value becomes active markup rather than plain text. ### Attack Path 1. An attacker, compromised agent, or untrusted integration supplies malicious task metadata. 2. The application stores the value through task initialization or assignment operations. 3. A user requests an HTML report through `generateProgressReport('html')`. 4. `generateHtmlReport()` interpolates the malicious value directly into a table cell. 5. The generated report is opened in a browser or embedded in an HTML-capable interface. 6. The browser interprets the injected content as markup and may execute attacker-controlled JavaScript. ### Impact Assessment Successful exploitation permits script execution in the security context of the generated report. Depending on how the report is hosted or embedded, an attacker may be able to: - Read or alter report content visible to the browser. - Access data available to the report's origin. - ...[truncated 387 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. HTML-encode every untrusted value before inserting it into the report: ```javascript function escapeHtml(value) { return String(value) .replaceAll('&', '&') .replaceAll('<', '<') .replaceAll('>', '>') .replaceAll('"', '"') .replaceAll("'", '''); } ``` Apply the function to all dynamic fields: ```javascript <td>${escapeHtml(task.name)}</td> <td>${escapeHtml(task.status)}</td> <td>${escapeHtml(task.progress)}%</td> <td>${escapeHtml(task.assignedAgent)}</td> ``` 2. Prefer a template engine that enables automatic HTML escaping by default. 3. Validate task status and progress against strict schemas. For example, require status to be one of the supported values and progress to be a finite number from 0 through 100. 4. If reports are served over HTTP, apply a restrictive Content Security Policy that disallows inline scripts and event handlers. 5. Add regression tests using payloads in every rendered task field and verify that the output contains encoded text rather than executable markup. ]]>
