T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/generate_html.py:218
- Finding
- Stored Cross-Site Scripting in the Generated HTML Report<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_html.py:218-242` and `scripts/generate_html.py:286-313` **Vulnerability Type**: Stored Cross-Site Scripting (Stored XSS) **Risk Level**: Medium ### Vulnerable Code ```python for cat in categories: html += f' <option value="{cat}">{cat}</option>\n' html += f''' </select> </div> <div class="filter-group"> <label>搜索</label> <input type="text" id="searchInput" placeholder="输入关键词..."> </div> <button class="btn" onclick="resetFilters()">重置</button> </div> <div class="stats"> <span>显示 <span class="highlight" id="showCount">{len(items)}</span> / {len(items)} 条</span> </div> <div class="content"> <div class="hot-list" id="hotList"></div> </div> <script> const items = {json.dumps(items, ensure_ascii=False)}; const categoryColors = {json.dumps(CATEGORY_COLORS, ensure_ascii=False)}; ``` ```python let html = ''; Object.keys(grouped).sort().reverse().forEach(date => {{ html += grouped[date].map(item => {{ const bgColor = categoryColors[item.category] || '#868e96'; return ` <a href="${{item.url}}" class="hot-item" target="_blank" style="text-decoration: none; color: inherit;"> <div class="rank ${{getRankClass(item.rank)}}">${{item.rank}}</div> <div class="item-content"> <div class="item-title">${{item.title}}</div> <div class="item-meta"> <span class="category-badge" style="background: ${{bgColor}}">${{item.category}}</span> <span style="color: #999;">${{item.date}}</span> </div> </di ...[truncated 4463 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Do not render remote data through `innerHTML`.** Build each item with DOM APIs and assign untrusted strings through `textContent`. ```javascript const title = document.createElement('div'); title.className = 'item-title'; title.textContent = item.title; ``` 2. **Store serialized data in a non-executable element.** For example, use `<script type="application/json">`, then parse its text content. Before embedding JSON in HTML, escape characters significant to the HTML parser, including `<`, `>`, and `&`. ```python serialized_items = json.dumps(items, ensure_ascii=False) serialized_items = ( serialized_items .replace('&', '\\u0026') .replace('<', '\\u003c') .replace('>', '\\u003e') ) ``` 3. **Apply context-specific HTML escaping** to values written into server-generated markup, including dates and category names. ```python from html import escape safe_cat_text = escape(str(cat)) safe_cat_attr = escape(str(cat), quote=True) html += f'<option value="{safe_cat_attr}">{safe_cat_text}</option>' ``` 4. **Validate links before assigning them.** Parse each URL and allow only HTTPS links to the expected Baidu host. Reject unsafe schemes such as `javascript:` and `data:`. 5. **Add `rel="noopener noreferrer"`** to links opened with `target="_blank"`. 6. **Deploy a restrictive Content Security Policy.** Prefer external JavaScript and disallow inline script execution, for example with a policy based on `script-src 'self'`. A CSP should be defense in depth rather than a substitute for output encoding. 7. **Validate upstream fields.** Enforce expected types, reasonable maximum lengths, and allowed category values before persistence. 8. **Add regression tests** using payloads containing `</script>`, quotes, HTML closing tags, event-handler attributes, and unsafe URL schemes. Verify that generated reports display these payloads as inert text. ]]>
