T09 · Insecure Skill Coding Practices
- Location
scripts/render_youtube_creator_report.py:69- Finding
Manifest-Controlled Markdown and HTML Injection in Generated Reports
- Content
View full analysis
str: text = str(value or "").strip() if not text: return "n/a" text = redact_secret_like_text(text) return URL_PATTERN.sub(lambda match: safe_public_url(match.group(0)), text) ``` Several manifest fields are then inserted directly into Markdown, including fields that do not pass through `sanitize_text()`: ```python lines = [ "# OpenClaw YouTube Publish Report", "", f"- Run: `{run.get('run_id', '')}`", f"- Channel: {sanitize_text(run.get('channel', ''))}", f"- Goal: {sanitize_text(run.get('goal', ''))}", f"- Browser profile: {safe_browser_profile(run.get('browser_profile', ''))}", f"- Kind: {run.get('kind', '')}", f"- Stage: {run.get('stage', '')}", f"- Visibility: {run.get('visibility', '')}", f"- Audience: {run.get('audience', '')}", f"- Studio URL: {safe_public_url(run.get('target_url', ''))}", f"- Video file: {safe_display_path(assets.get('video_file', ''))}", f"- Title: {sanitize_text(assets.get('title', ''))}", ``` ```python for index, step in enumerate(steps, start=1): lines.append(f"### {index}. {step.get('step_id', f'step-{index}')}") lines.append(f"- Surface: {sanitize_text(step.get('surface', ''))}") lines.append(f"- Status: **{step.get('status', 'unknown')}**") ``` ### Technical Analysis The report renderer treats manifest content as trusted Markdown. The `sanitize_text()` function only redacts selected secret-like strings and replaces HTTP or HTTPS URLs according to an allowlist. It does not escape Markdown metacharacters or neutralize raw HTML. Moreover, fields such as `run_id`, `kind`, `stage`, `visibility`, `audience`, `step_id`, and `status` bypass `sanitize_text() ...[truncated 2420 chars]- Remediation
View remediation
