T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/md2html.js:101
- Finding
- Unsanitized Markdown Conversion Enables HTML Injection and Cross-Site Scripting< — must come before links text = text.replace(/!\[(.+?)\]\((.+?)\)/g, '<img src="$2" alt="$1" style="max-width:100%;">'); // Bold **text** text = text.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>'); // Italic *text* (Node v0.12+ compatible, no lookbehind needed) text = text.replace(/\*([^*\n]+?)\*/g, '<em>$1</em>'); // Inline code `text` text = text.replace(/`(.+?)`/g, '<code>$1</code>'); // Links [text](url) text = text.replace(/\[(.+?)\]\((.+?)\)/g, '<a href="$2" target="_blank" rel="noopener">$1</a>'); // Line breaks (double space at end of line) text = text.replace(/ $/gm, '<br>'); return text; } ``` Representative output sinks include: ```javascript result.push('<h1>' + inlineFormat(line.replace(/^#\s*/, '')) + '</h1>'); result.push('<blockquote><p>' + inlineFormat(line.replace(/^>\s*/, '')) + '</p></blockquote>'); result.push('<li>' + inlineFormat(line.replace(/^[\-\*]\s*/, '')) + '</li>'); result.push('<p>' + inlineFormat(line) + '</p>'); ``` ### Technical Analysis The converter inserts untrusted Markdown content into generated HTML without first applying HTML escaping. The `inlineFormat()` function also places attacker-controlled image URLs, link URLs, alternative text, and labels directly into HTML attribute or element contexts. The only escaping routine in the project is applied to fenced code-block contents. Ordinary paragraphs, headings, list items, blockquotes, inline code, links, and images remain unsafe. This creates multiple exploitation mechanisms: 1. **Direct HTML injection**: Raw HTML in an ordinary Markdown line is preserved inside the generated paragraph. 2. **Attribute inje ...[truncated 2704 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Escape text before formatting** - HTML-escape all untrusted Markdown text before placing it into element content. - Encode at least `&`, `<`, `>`, `"`, and `'` where appropriate. - Ensure inline-code content is escaped rather than merely wrapped in `<code>`. 2. **Apply context-aware attribute encoding** - Never interpolate captured regular-expression groups directly into quoted attributes. - Encode image alternative text, image sources, link destinations, and any future attribute values using an attribute-safe encoder. 3. **Validate link and image URL schemes** - Parse URLs and allow only explicitly required schemes, such as `https:`, `http:`, and optionally `mailto:`. - Reject `javascript:`, unsafe `data:`, `vbscript:`, file URLs, control characters, encoded scheme bypasses, and protocol-relative URLs unless specifically required. - Validation must occur after normalization and decoding. 4. **Sanitize the final HTML** - Use a maintained Markdown implementation with secure configuration. - Pass generated HTML through an allowlist-based HTML sanitizer before publishing it. - Allow only necessary elements and attributes, and remove event-handler attributes and dangerous URL protocols. - If raw HTML is unnecessary, disable raw HTML support entirely. 5. **Harden browser integration** - Apply an appropriately restrictive Content Security Policy as defense in depth. - Do not treat converted output as trusted solely because it was produced by this converter. - Preserve `rel="noopener"` and consider adding `noreferrer` where suitable, but do not treat these attributes as an XSS mitigation. 6. **Add security regression tests** - Test raw elements such as `<script>` and `<img onerror>`. - Test quote-breaking payloads in image alt text and URLs. - Test dangerous and obfuscated URL schemes. - Test HTML inside headings, lists, blockquotes, and inline-code spans. - Confirm ...[truncated 302 chars]
