T09 · Insecure Skill Coding Practices
- Location
scripts/generate_heat_balance_viz.py:61- Finding
Stored HTML and JavaScript Injection in Generated Visualization Reports
- Content
View full analysis
{stage['name']}{stage['temp']}°C{stage['label']}''' # Generate energy distribution table energy_table_rows = "" for item in energy_distribution: energy_table_rows += f''' {item['item']} {item['percentage']}% {item['description']} ''' # Generate KPI cards kpi_cards = "" for kpi in kpis: kpi_cards += f'''''' ``` ### Technical Analysis The `process_stages`, `energy_distribution`, and `kpis` collections originate from JSON supplied through either `--input` or `--data`. Their fields are interpolated into the resulting HTML through Python f-strings without HTML encoding. Most values are inserted into HTML text contexts, where a payload containing closing tags and event-handler markup can terminate the intended element and introduce executable content. For example, a stage name could contain: ```html{kpi['value']}{kpi['label']}``` The `stage['type']` field is especially sensitive because it is inserted inside a quoted `class` attribute. An ...[truncated 1881 chars]- Remediation
View remediation
str: return escape(str(value), quote=True) ``` Apply this function to stage names, labels, energy-distribution text, KPI values, and all other text fields. 2. Do not treat `stage['type']` as arbitrary text. Validate it against an explicit allowlist: ```python allowed_stage_types = {"cold", "normal", "hot"} stage_type = str(stage.get("type", "normal")) if stage_type not in allowed_stage_types: stage_type = "normal" ``` 3. Enforce data types and reasonable ranges for numeric fields before rendering: ```python temperature = float(stage["temp"]) percentage = float(item["percentage"]) if not -273.15 <= temperature <= 3000: raise ValueError("Temperature is outside the permitted range") if not 0 <= percentage <= 100: raise ValueError("Percentage must be between 0 and 100") ``` 4. Prefer a mature template engine configured with automatic HTML escaping rather than assembling markup through raw f-strings. 5. Add regression tests containing characters such as `<`, `>`, `"`, `'`, and `&`, as well as complete event-handler payloads. Verify that the resulting report contains encoded text and no attacker-created elements or attributes. 6. If reports are hosted by a web application, apply a restrictive Content Security Policy that disallows inline scripts and event handlers. This should be defense in depth and must not replace output encoding and input validation. ]]>
