T09 · Insecure Skill Coding Practices
- Location
scripts/smartsheet_filter.py:428- Finding
Stored HTML and JavaScript Injection in Generated Reports
- Content
View full analysis
', '', '', '', '', f'{title}', '', # Static CSS omitted '', '', '', '', f'{title}
', f'共筛选出 {len(results)} 条结果
', '', f'共 {len(results)} 条', '', '', ] # 表头 for t in resolved_titles: html_parts.append(f'') html_parts.append('') # 行 for i, row in enumerate(results, 1): html_parts.append(f'') for t in resolved_titles: val = row.get(t, "") if val.startswith("http"): val = f'{val}' else: val = val.replace("<", "<").replace(">", ">") html_parts.append(f'') ``` ### Technical Analysis The HTML generator interpolates several untrusted or externally influenced values directly into HTML: - The report `title` is inserted into both `` and `<h1>` without escaping. - Column titles from the processed spreadsheet are inserted into `<th>` elements without escaping. - Cell values beginning with `http` are inserted into an `href` attribute and anchor body without any attribute escaping. - Other cell values only replace `<` and `>`. This is incomplete HTML encoding and does not provide safe contextual handling for all output locations. The URL branch is particularly dangerous because a malicious spreadsheet value can begin with `http` while containing a qu ...[truncated 2392 chars]# {t} {i} {val} - Remediation
View remediation
str: return html.escape(str(value), quote=True) def is_allowed_url(value: str) -> bool: try: parsed = urlparse(value) return parsed.scheme.lower() == "https" and bool(parsed.netloc) except (TypeError, ValueError): return False safe_title = escape_html(title) html_parts.append(f"{safe_title}") html_parts.append(f"{safe_title}
") for column_title in resolved_titles: html_parts.append(f"{escape_html(column_title)}") for column_title in resolved_titles: raw_value = str(row.get(column_title, "")) safe_value = escape_html(raw_value) if is_allowed_url(raw_value): html_parts.append( f'
