T09 · Insecure Skill Coding Practices
Note
- Location
- skill.js:153
- Finding
- Markdown Injection in Generated Report<![CDATA[ ## Vulnerability Details **File Location**: `skill.js`, lines 153-178 **Vulnerability Type**: Improper neutralization of Markdown syntax in user-controlled report fields **Risk Level**: Low ### Vulnerable Code ```js function mdEscape(s) { return String(s ?? "").replace(/</g, "<").replace(/>/g, ">"); } function cmdRun(args) { const preset = args.preset; const task = args.task || ""; if (!preset) return fail("Missing --preset"); if (!task) return fail("Missing --task"); if (!PRESETS[preset]) return fail(`Unknown preset: ${preset}`); const db = loadNames(); const teamNames = getOrInitTeam(db, preset); saveNames(db); const started = nowIso(); const ended = nowIso(); const runId = `run_${Date.now()}`; const team = PRESETS[preset].roles.map(r => { const nickname = teamNames[r.key]; return { nickname, role: r.archetype, objective: r.objective, output: "(MVP placeholder) — integrate actual multi-agent reasoning in Pro/Max.", artifacts: [] }; }); const oneLine = `Completed preset '${preset}' on task: ${task.slice(0, 80)}${task.length > 80 ? "…" : ""}`; const reportMarkdown = `# AOI Squad Report (v0.1)\n- Preset: ${mdEscape(preset)}\n- Run: ${mdEscape(runId)}\n- Time: ${mdEscape(started)} → ${mdEscape(ended)}\n\n## Task\n${mdEscape(task)}\n\n## Team outputs\n${team.map(m => `### ${mdEscape(m.nickname)} (${mdEscape(m.role)})\n- Objective: ${mdEscape(m.objective)}\n- Output: ${mdEscape(m.output)}\n`).join("\n")}\n## Synthesis\n- One-line: ${mdEscape(oneLine)}\n- Decision:\n - (placeholder)\n- Risks:\n - (placeholder)\n- Next actions:\n - [P1] Review and refine outputs (Owner: ${mdEscape(team[0].nickname)})\n- VCP Proof:\n - (none)\n`; ``` ### Technical Analysis The `mdEscape()` function escapes only the `<` and `>` characters. It does not neutralize Markdown control syntax such as image declarations, links, headings, blockquotes, or formatting delimiters. The unrestric ...[truncated 2161 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Use a well-maintained, context-aware Markdown escaping or sanitization library rather than replacing only angle brackets. 2. Treat untrusted task text and nicknames as plain text. Escape all Markdown metacharacters where inline insertion is required. 3. Consider placing the task in a fenced code block while safely handling embedded fence delimiters, or omit the Markdown representation and rely on the structured JSON fields. 4. Configure downstream renderers to: - Disable remote image loading. - Reject unsafe or unapproved URL schemes. - Sanitize generated HTML. - Add `rel="noopener noreferrer"` to external links where applicable. 5. Add regression tests covering image syntax, links, headings, blockquotes, nested formatting, multiline input, and attempts to break out of any chosen containment context. ]]>
