T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/generate_reports.py:585
- Finding
- Stored JavaScript Injection in Generated HTML Dashboards<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_reports.py:585-592`; `assets/dashboard_template.html:569-617` **Vulnerability Type**: Stored JavaScript injection / DOM-based cross-site scripting **Risk Level**: High ### Vulnerable Code ```python content = content.replace('{{SALES_TREND_DATA}}', json.dumps(chart_data['sales_trend'], ensure_ascii=False)) content = content.replace('{{PRICE_TREND_DATA}}', json.dumps(chart_data['price_trend'], ensure_ascii=False)) content = content.replace('{{PRICE_DIST_DATA}}', json.dumps(chart_data['price_dist'], ensure_ascii=False)) content = content.replace('{{RATING_DIST_DATA}}', json.dumps(chart_data['rating_dist'], ensure_ascii=False)) content = content.replace('{{BRAND_SHARE_DATA}}', json.dumps(chart_data['brand_share'], ensure_ascii=False)) content = content.replace('{{SELLER_SOURCE_DATA}}', json.dumps(chart_data['seller_source'], ensure_ascii=False)) content = content.replace('{{BRAND_RATING_TREND_DATA}}', json.dumps(chart_data['brand_rating_trend'], ensure_ascii=False)) content = content.replace('{{TOP50_PRODUCTS}}', json.dumps(chart_data['top50_products'], ensure_ascii=False)) ``` The resulting data is inserted into an executable script block and later passed to `innerHTML`: ```javascript const top50Products = {{TOP50_PRODUCTS}}; const tableBody = document.getElementById('top50TableBody'); top50Products.forEach((product, index) => { const row = tableBody.insertRow(); row.innerHTML = ` <td>${index + 1}</td> <td>${product.asin}</td> <td style="text-align:left;">${product.title}</td> <td>${product.brand}</td> <td>$${product.price}</td> <td>${product.rating}</td> <td>${product.sales}</td> <td>${product.marketShare}%</td> `; }); ``` ### Technical Analysis Product titles, brands, ASINs, seller-source values, and trend fields can originate from the external Sorftime API or from a user-supplied JSON file. These fields are se ...[truncated 2114 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Do not use `innerHTML` for API-derived values. Construct each cell separately and assign content through `textContent`: ```javascript const cell = row.insertCell(); cell.textContent = String(product.title ?? ''); ``` 2. Store serialized report data in a non-executable JSON element: ```html <script id="report-data" type="application/json">...</script> ``` Parse it with: ```javascript const reportData = JSON.parse( document.getElementById('report-data').textContent ); ``` 3. Before embedding JSON into HTML, escape at least `<`, `>`, `&`, U+2028, and U+2029. In particular, encode `<` as `\u003c` so `</script>` cannot terminate the element. 4. HTML-escape category names, site values, and all other variables inserted into normal HTML contexts. 5. Add a restrictive Content Security Policy that blocks inline event handlers and limits script sources. Prefer external, locally hosted scripts with nonce- or hash-based authorization. 6. Add regression tests using values containing `</script>`, `<img src=x onerror=alert(1)>`, quotation marks, backticks, and Unicode line separators. ]]>
