T09 · Insecure Skill Coding Practices
- Location
handler.js:96- Finding
Unescaped Contact Data Allows Markdown and HTML Content Injection
- Content
View full analysis
Vulnerability Details
File Location:
handler.js, lines 96–111
Vulnerability Type: Improper output encoding for Markdown content
Risk Level: MediumVulnerable Code
js for (const c of overdue) { const hook = c.lastTopic.split(" ").slice(0, 6).join(" ") + "..."; lines.push( `| ${c.name} | ${c.category} | ${c.days}d | +${c.overdue}d | ${hook} |` ); } lines.push(""); lines.push("---"); lines.push(""); lines.push("**Draft Messages:**\n"); for (const c of overdue) { const draft = draftMessage(c); lines.push(`**${c.name}** (${c.contactMethod}):`); lines.push(`> ${draft}\n`); }The generated draft also incorporates unescaped contact data through
draftMessage():js const topic = contact.lastTopic; const name = contact.name.split(" ")[0]; const templates = [ `Hey ${name}, I saw something that reminded me of you — ${topic.toLowerCase()}. How's that going?`, `Hey ${name}! I was just thinking about ${topic.toLowerCase()}. Any updates? Would love to catch up.`, `${name}! It's been a minute. Last time we talked ${topic.toLowerCase()} — still on that? Let's reconnect soon.`, ];Technical Analysis
Values originating from a contacts file—including
name,category,lastTopic, andcontactMethod—are interpolated directly into Markdown output without contextual escaping or schema validation. Markdown control characters, raw HTML, links, images, block delimiters, and table separators can therefore alter the structure and meaning of the generated report.For example, a crafted
lastTopiccan introduce a remote image or deceptive link. A craftednamecontaining table separators or line breaks can terminate the intended table cell and inject additional report content. Whether raw HTML or remote resources become active depends on the downstream Markdown renderer and its security configuration.The issue is classified as `T09: Insecure Ski ...[truncated 1916 chars]
- Remediation
View remediation
Remediation Suggestions
- Validate the complete contacts document immediately after JSON parsing. Require an array of objects with bounded string fields and enforce documented enumerations for
categoryandcontactMethod. - Escape all Markdown metacharacters according to the output context. Table cells must escape at least pipes, backslashes, HTML delimiters, and line breaks. Draft text must separately escape Markdown links, images, block markers, and raw HTML.
- Normalize or reject carriage returns and newline characters in fields intended to remain on one output line.
- Apply reasonable maximum lengths to names, topics, categories, and contact methods to prevent output manipulation and resource abuse.
- Configure the downstream Markdown renderer to disable raw HTML and automatic remote-resource loading. Apply a restrictive content security policy where rendered output is displayed in a browser.
- Prefer a structured return format such as JSON and let a trusted presentation layer perform context-aware encoding.
- Add security tests using contact values containing table separators, line breaks, Markdown links, image syntax, and raw HTML to verify that they are displayed as literal text rather than interpreted markup.
- Validate the complete contacts document immediately after JSON parsing. Require an array of objects with bounded string fields and enforce documented enumerations for
