T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/slides_json_to_pptx.py:39
- Finding
- Unvalidated SVG Content Is Embedded Verbatim into Generated PPTX Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/slides_json_to_pptx.py:39-53`; `scripts/embed_svg_to_pptx.py:190-194` **Vulnerability Type**: Missing validation and sanitization of untrusted SVG content **Risk Level**: Medium ### Vulnerable Code ```python for index, slide in enumerate(slides, start=1): if not isinstance(slide, dict): raise ValueError(f"slide {index} is not an object") title = slide.get("title") svg = slide.get("svg") if not isinstance(title, str) or not title.strip(): raise ValueError(f"slide {index} is missing a non-empty title") if not isinstance(svg, str) or not svg.strip(): raise ValueError(f"slide {index} is missing a non-empty svg") return slides def _write_svgs(slides: list[dict], svg_dir: Path) -> list[Path]: svg_dir.mkdir(parents=True, exist_ok=True) svg_paths: list[Path] = [] for index, slide in enumerate(slides, start=1): svg_path = svg_dir / f"slide_{index:03d}.svg" svg_path.write_text(slide["svg"], encoding="utf-8") svg_paths.append(svg_path) ``` The resulting file is subsequently copied directly into the PPTX package: ```python for index, svg_path in enumerate(svg_paths, start=1): media_name = f"slide_{index:03d}.svg" shutil.copyfile(svg_path, media_dir / media_name) ``` ### Technical Analysis The loader verifies only that the `svg` property is a non-empty string. It does not parse the document or enforce the SVG restrictions described in `SKILL.md`, such as rejecting scripts, styles, filters, HTML content, or unsupported elements. Consequently, attacker-controlled slide JSON or compromised model output can introduce arbitrary XML and SVG features into the generated presentation. Potentially dangerous content includes: - `script` elements and SVG event-handler attributes. - `foreignObject` elements containing HTML. - External resource references through `href`, `xlink:href`, CSS, or image elements. - DTD declarations o ...[truncated 1769 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Parse the submitted content with an XML parser configured to reject DTDs and external entities. 2. Require exactly one SVG root element with the expected SVG namespace and `viewBox="0 0 1280 720"`. 3. Implement an allowlist of permitted SVG elements and attributes. 4. Explicitly reject: - `script`, `style`, `foreignObject`, and animation elements. - Attributes beginning with `on`, such as `onclick` and `onload`. - DTDs, entities, processing instructions, and non-SVG namespaces. - External or protocol-based references in `href`, `xlink:href`, CSS, and URL-valued attributes. - `data:` URLs unless a narrowly defined, size-limited use case requires them. - The prohibited `filter` element and `filter` attributes. 5. Serialize the validated parsed tree rather than embedding the original input string. 6. Apply limits to SVG size, XML nesting depth, element count, path complexity, and number of slides to mitigate resource-exhaustion attacks. 7. Add negative tests covering scripts, event handlers, `foreignObject`, external images, entity declarations, malformed XML, and oversized SVG documents. ]]>
