Question presented to candidate: "Build a Markdown previewer: a text area on the left, the rendered result on the right, updating as you type. Write the parser yourself for a small subset, no marked or markdown-it. Users will paste anything into it, so make sure it cannot be used to run scripts."
Requirements:
- Live preview of a subset:
#to###headings, paragraphs (consecutive lines join),**bold**,*italic*, inline code, fenced code blocks,-and1.lists,>quotes,---rules and[text](url)links. - Escape all user text before adding any tags, so raw HTML such as
<img onerror>or<script>shows as text. - Links only for safe schemes (
http:,https:,mailto:,#,/);javascript:and the rest stay plain text; links open in a new tab withrel="noopener noreferrer". - Code spans and code blocks are escaped and never formatted inside.
- A toggle to show the generated HTML source; a two-column layout that stacks on narrow screens.
What a strong answer should cover:
- A two-level parser: block pass over lines (headings, lists, quotes, fences, paragraphs) and an inline pass (code, links, bold, italic).
- Escape first, then format: why the order matters and why attribute values need
"escaped too. - URL scheme allowlisting rather than blocklisting
javascript:. - Rendering the HTML string (
dangerouslySetInnerHTML,v-html,[innerHTML]) and what each framework does or does not sanitise. - Proving the XSS defence with real payloads, and when to reach for a library plus DOMPurify instead.
Clarifying questions expected:
- "Which Markdown features are in scope: nested lists, tables, images, raw HTML passthrough?"
- "Is the input trusted (our own docs) or from any user?"
- "Does the preview need to be fast for very large documents?"
Code / implementation expected: Yes. A pure markdownToHtml function with an escapeHtml helper, and an editor plus preview component, with a demonstration that XSS payloads render as text.