T09 · Insecure Skill Coding Practices
Warning
- Location
- reporter.py:32
- Finding
- Stored HTML and JavaScript Injection in Generated Reports<![CDATA[ ## Vulnerability Details **File Location**: `reporter.py:32`, `reporter.py:69`, and `reporter.py:95-103` **Vulnerability Type**: Stored HTML injection / cross-site scripting in a locally generated report **Risk Level**: Medium ### Vulnerable Code ```python <title>投放数据分析报告 - {date_range}</title> ``` ```python <div class="timestamp">日期范围: {date_range} | 生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</div> ``` ```python <div class="section"> <h2>🔍 数据样本</h2> <h3>超级直播数据(前5行)</h3> <pre>{super_df.head().to_string() if not super_df.empty else '无数据'}</pre> <h3>淘宝直播数据(前5行)</h3> <pre>{taobao_df.head().to_string() if not taobao_df.empty else '无数据'}</pre> <h3>财务报表数据(前5行)</h3> <pre>{financial_df.head().to_string() if not financial_df.empty else '无数据'}</pre> </div> ``` ### Technical Analysis The report generator interpolates dynamic values directly into an HTML document without HTML escaping. The affected values include: - The `date_range` value supplied through an environment variable or command-line argument. - DataFrame column names and cell values loaded from input data files. - The first five rows of each advertising or financial dataset. An HTML `<pre>` element preserves formatting but does not treat its contents as inert text. An attacker-controlled value containing markup such as: ```html </pre><script>alert(document.domain)</script><pre> ``` can terminate the existing `<pre>` element and introduce executable HTML or JavaScript into the generated report. Because the payload is saved in the report, this is a stored injection issue: execution occurs when a user opens the generated HTML file in a browser. The application does not add a Content Security Policy that would prevent inline script execution. ### Attack Path 1. An attacker creates or modifies a CSV file whose filename contains one of the recognized keywords, such as the keyword for a live-stream or financial report. 2. The attacker places a malicious HT ...[truncated 1553 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Escape every untrusted value before inserting it into HTML: ```python from html import escape safe_date_range = escape(str(date_range), quote=True) safe_super_preview = escape( super_df.head().to_string() if not super_df.empty else "No data", quote=True ) ``` 2. Use the escaped values in the template rather than the original values: ```python <title>Advertising Data Analysis Report - {safe_date_range}</title> <pre>{safe_super_preview}</pre> ``` 3. Prefer structured DataFrame rendering with escaping enabled: ```python super_preview = ( super_df.head().to_html(index=False, escape=True) if not super_df.empty else "<p>No data</p>" ) ``` Apply the same protection to the Taobao and financial previews, metric names, recommendation text, date ranges, and any other dynamic values added to the report. 4. Validate `date_range` against the documented format before using it: ```python import re if not re.fullmatch(r"\d{4}-\d{2}-\d{2}:\d{4}-\d{2}-\d{2}", date_range): raise ValueError("Invalid date range format") ``` 5. Add a restrictive Content Security Policy to reduce the impact of any future escaping mistake: ```html <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; img-src data:"> ``` 6. Add regression tests using payloads in the date range, column names, and cell values. Verify that generated reports contain encoded forms such as `<script>` and do not contain executable attacker-supplied elements. ]]>
