T09 · Insecure Skill Coding Practices
- Location
assets/report_template.html:237- Finding
Stored HTML and JavaScript Injection in Generated Reports
- Content
View full analysis
{{REPORT_TITLE}}{{REPORT_SUBTITLE}}...{{INSIGHTS}}``` ```javascript (function renderSummaryCards() { const container = document.getElementById('summary-cards'); if (!SUMMARY_STATS || Object.keys(SUMMARY_STATS).length === 0) { container.style.display = 'none'; return; } const entries = Object.entries(SUMMARY_STATS); const displayCols = entries.slice(0, 5); container.innerHTML = displayCols.map(([key, val]) => ``).join(''); })(); ``` ```javascript const rows = Object.entries(stats).map(([name, s]) => { const cells = [name, s.mean, s.median, s.std, s.min, s.max, s.sum, s.cv].map(v => typeof v === 'number' ? formatNum(v) : (v || '-') ); return '' + cells.map(c => `${c}`).join('') + ''; }).join(''); ``` ```javascript return `${key}${formatNum(val.mean)}Range: ${formatNum(val.min)} – ${formatNum(val.max)}`; ... sectionContainer.innerHTML = html; ``` Spreadsheet column names are preserved by the analyzer: ```python for col in df.columns: ctype = detect_column_type(df[col], col) dtype = str(df[col].dtype) unique = int(df[col].nunique()) columns_info.append({ "name": str(col), "type": ctype, "dtype": dtype, "unique": unique, "missing": int ...[truncated 2404 chars]${chart.title}- Remediation
View remediation
`, `&`, U+2028, and U+2029. Prefer loading JSON from an `application/json` element and parsing its `textContent`. 4. Sanitize `INSIGHTS` with a strict allowlist if formatted HTML is required. Otherwise, render insights as plain text. 5. Generate chart element IDs internally and restrict them to a safe character set rather than deriving them from column names. 6. Add a restrictive Content Security Policy that disallows inline event handlers and limits script sources. Remove inline scripting where practical. 7. Add regression tests using malicious column names, including HTML elements, quotes, closing script tags, and encoded variants. ]]>
