T09 · Insecure Skill Coding Practices
- Location
scripts/social_kit.py:891- Finding
Stored HTML Injection in Generated Content Calendars
- Content
View full analysis
{meta['brand']} — Social Media Content Calendar ``` ```python🎯 {theme['name']}``` ```python return f"""{_esc(post['day_name'])} · Day {post['day']}{_esc(post['date'])} · ⏰ {_esc(post['best_time'])}{post['content_type_emoji']} {post['content_type_label']} ``` The `calendar` command loads user-supplied JSON directly: ```python with open(json_path, "r", encoding="utf-8") as f: calendar_data = json.load(f) generate_html_calendar(calendar_data, output_path) ``` ### Technical Analysis Several values are interpolated directly into the generated HTML without contextual escaping: - `meta['brand']` is inserted into the `` element. - `theme['name']` is inserted into an HTML element. - `post['content_type']` is inserted into CSS class attributes. - `content_type_emoji` and `content_type_label` are inserted as HTML content. These values can originate from command-line or stdin input, and the `calendar` command also accepts an arbitrary JSON document without schema validation. Although the project defines an `_esc()` function and uses it for several other fields, the affected values bypass that function. For example, a crafted brand value containing: ```html ``` would terminate the existing ti ...[truncated 1855 chars]- Remediation
View remediation
{_esc(meta['brand'])} — Social Media Content Calendar🎯 {_esc(theme['name'])}``` 2. Escape display fields in post cards: ```python {_esc(post['content_type_emoji'])} {_esc(post['content_type_label'])} ``` 3. Do not rely on HTML escaping for CSS class fragments. Validate `content_type` against a strict allowlist: ```python allowed_types = set(CONTENT_TYPES) ct = post.get("content_type") if ct not in allowed_types: raise ValueError(f"Invalid content type: {ct!r}") ``` 4. Validate imported JSON before rendering. Enforce expected types, required fields, supported platform names, content-type values, bounded numeric fields, and reasonable string lengths. 5. Prefer a template engine with automatic HTML escaping and use explicit validation for values inserted into attributes or CSS class names. 6. Add regression tests using payloads that attempt to escape title, element-content, and attribute contexts. Verify that generated output contains escaped text and no executable `
