T09 · Insecure Skill Coding Practices
- Location
scripts/process_turtle.py:112- Finding
Unescaped configuration values permit active SVG/XML injection
- Content
View full analysis
str: return f'''{text}''' def _node(self, x: int, y: int, name: str, node_type: str = 'process', color: str = None) -> str: w, h = self.STYLES['node_width'], self.STYLES['node_height'] r = self.STYLES['radius'] if color is None: color = self.COLORS['node'].get(node_type, self.COLORS['node']['process']) if node_type == 'start' or node_type == 'end': return f''' {name}''' elif node_type == 'decision': s = self.STYLES['decision_size'] points = f"{x},{y-s//2} {x+s//2},{y} {x},{y+s//2} {x-s//2},{y}" return f''' {name}''' else: return f''' {name}'' ...[truncated 3350 chars]- Remediation
View remediation
str: return escape(str(value), { '"': """, "'": "'", }) ``` Apply this function consistently to: - `config.title` - `node.name` - `node.category` and lane names - `edge.label` - Any future user-controlled attribute or text value 2. Prefer an XML construction library such as `xml.etree.ElementTree` rather than assembling SVG through formatted strings. Assign untrusted content through element `.text` fields so the serializer performs escaping. 3. Validate configuration values before generation. Enforce expected types, reasonable length limits, and allowed values for fields such as node type and turtle category. 4. If generated SVGs are served by a web application, apply defense in depth: - Serve them with `Content-Type: image/svg+xml`. - Use `Content-Disposition: attachment` when inline display is unnecessary. - Apply a restrictive Content Security Policy. - Serve untrusted SVGs from an isolated origin without sensitive cookies. - Consider sanitizing SVG output or converting it to a non-active raster format before publication. 5. Add regression tests using benign metacharacters and malicious payloads: ```text A & B``` Verify that these values appear only as escaped text and cannot create new SVG elements. ]]>
