T09 · Insecure Skill Coding Practices
- Location
scripts/selfie.py:149- Finding
Stored HTML Injection in the Generated Gallery
- Content
View full analysis
None: thumbs = "\n".join( [ f'\n' f'\n' f' {it["prompt"]}\n' f'' for it in items ] ) ``` The injected value originates from personality data accepted by `load_personality()` and incorporated into the prompt by `build_prompt()`: ```python merged = dict(DEFAULT_PERSONALITY) merged.update({k: v for k, v in data.items() if v}) return merged ``` ### Technical Analysis The `name`, `style`, and `vibe` personality properties may come from an inline JSON argument or a user-supplied JSON file. These values are interpolated into the generated prompt without type validation or HTML output encoding. The resulting prompt is then inserted directly into a `` element. An attacker-controlled value containing HTML, such as a closing `figcaption` tag followed by a `script` element or an event-handler attribute, is therefore interpreted as markup when the gallery is opened. The generated `index.html` is a persistent artifact, making this a stored injection issue rather than a transient display problem. Exploitation requires the user or another application to open or host the generated gallery. ### Attack Path 1. An attacker supplies or convinces the user to use a personality JSON file containing malicious HTML in a personality field. 2. `load_personality()` accepts the value without restricting it to safe plain text. 3. `build_prompt()` incorporates the malicious value into the prompt. 4. Image generation completes, and the prompt is stored in the gallery item. 5. `write_gallery()` inserts the prom ...[truncated 715 chars]
- Remediation
View remediation
`, ``, quotes, and event-handler attributes. - If galleries may be hosted, deploy a restrictive Content Security Policy that disallows inline scripts as defense in depth. ]]>
