T09 · Insecure Skill Coding Practices
- Location
scripts/generate_postmortem.py:398- Finding
Stored HTML and Script Injection in Generated Reports
- Content
View full analysis
\1', html, flags=re.MULTILINE) html = re.sub(r'^## (.+)$', r'\1
', html, flags=re.MULTILINE) html = re.sub(r'^### (.+)$', r'\1
', html, flags=re.MULTILINE) # Bold html = re.sub(r'\*\*(.+?)\*\*', r'\1', html) # Italic html = re.sub(r'_(.+?)_', r'\1', html) # Code html = re.sub(r'`(.+?)`', r'\1', html) # Lists html = re.sub(r'^- (.+)$', r'- \1
', html, flags=re.MULTILINE) # Tables (simple conversion) def convert_table(match): lines = match.group(0).strip().split('\n') rows = [] for i, line in enumerate(lines): if '---' in line: continue cells = [c.strip() for c in line.strip('|').split('|')] tag = 'th' if i == 0 else 'td' row = ''.join(f'<{tag}>{c}' for c in cells) rows.append(f'{row}') return f'{"".join(rows)}' html = re.sub(r'(\|.+\|(?:\n\|.+\|)*)', convert_table, html) # Paragraphs (lines not already wrapped) lines = html.split('\n') processed = [] for line in lines: if line.strip() and not line.strip().startswith('<') and not line.strip().startswith('*'): processed.append(f'
{line}
') else: processed.append(line) html = '\n'.join(processed) return f"""- Remediation
View remediation
` value separately and always escape it before interpolation. 5. Add a restrictive Content Security Policy, such as a policy that disallows scripts and plugins, as defense in depth. Sanitization and escaping must remain the primary controls. 6. Add regression tests covering: - `` - `` - `` - `javascript:` URLs - Payloads in titles, summaries, timeline events, action items, and log messages 7. Document that input logs and JSON files may be untrusted and that generated HTML must not be published until sanitization is implemented. ]]>
