T09 · Insecure Skill Coding Practices
- Location
scripts/generate_svg.py:261- Finding
Untrusted JSON Content Is Embedded Verbatim into Generated SVG Files
- Content
View full analysis
Vulnerability Details
File Location:
scripts/generate_svg.py, lines 261–267 and 285–289
Vulnerability Type: Active SVG/XML markup injection
Risk Level: HighVulnerable Code
python def make_svg(body_content: str) -> str: """Wrap content in complete SVG document.""" return f'''<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720"> <rect width="1280" height="720" fill="#FFFFFF"/> {body_content} </svg>'''python pages = data.get('pages', []) for i, page in enumerate(pages, 1): content = page.get('content', '') out_path = output_dir / f'page_{i:02d}.svg' out_path.write_text(make_svg(content), encoding='utf-8')Technical Analysis
The script reads
pages[].contentfrom an arbitrary JSON input file and interpolates it directly into an SVG document without parsing, validation, sanitization, or escaping.Although the module provides
escape_svg()for text passed through its slide-building helpers, the main generation path does not use those helpers. Instead, it treats the entirecontentfield as trusted SVG markup. Consequently, an attacker can insert arbitrary SVG/XML elements and attributes, including:<script>elements- Event handlers such as
onloadoronclick - External resource references through
href - Interactive links
<foreignObject>containing active HTML- Other SVG features with behavior dependent on the consuming application
This is an active-content injection issue rather than ordinary text injection. The generated artifact cannot be considered a passive presentation file when its input is untrusted.
Attack Path
-
An attacker creates or modifies the JSON file supplied to
generate_svg.py. -
The attacker places active SVG/XML markup in a
pages[].contentvalue. -
A user runs:
text generate_svg.py <input.json> <output_dir> -
The script loads the attacker-controlled value and passes it unchanged to ...[truncated 1391 chars]
- Remediation
View remediation
Remediation Suggestions
-
Replace raw SVG input with a structured schema. Define allowed page types, text fields, dimensions, colors, and layout options. Generate all SVG elements internally rather than accepting an arbitrary markup string.
-
Escape all untrusted text and attribute values. Route text through
escape_svg()and validate values used in XML attributes. Escaping text alone is insufficient if users can control complete tags or attributes. -
Apply strict allowlist sanitization if raw SVG support is required. Parse the content with a hardened XML parser and retain only explicitly approved presentation elements and attributes.
-
Reject active or externally connected features, including:
scriptforeignObject- Event attributes beginning with
on - External
hreforxlink:hrefvalues - Remote images, stylesheets, and fonts
- Unsafe namespace declarations
- Animation or event features capable of triggering active behavior
-
Reject malformed or unexpected input types. Verify that
pagesis a list, each page is an object, and every permitted property has the expected type, range, and maximum length. -
Add regression tests using payloads containing
<script>,onload, externalhref, and<foreignObject>. Tests should verify that these constructs are rejected or rendered as inert text. -
Document the trust boundary. Until sanitization is implemented, warn users not to process JSON files from untrusted sources and not to open generated SVG files in browser contexts.
-
