Question presented to candidate:
"Product wants user comments to support bold and links, and someone suggests rendering them with v-html. What does v-html do, what is the danger, and what would you do instead?"
What a strong answer should cover:
v-html="value"sets the element'sinnerHTML, so the string is parsed as real HTML. Interpolation{{ value }}sets text and escapes HTML.- With untrusted input it enables cross-site scripting (XSS): event-handler attributes like
onerror,javascript:URLs and similar vectors run attacker JavaScript in your origin. (<script>tags inserted throughinnerHTMLdo not run, which gives false confidence.) - Use it only with trusted content, or sanitize with a maintained allowlist library such as DOMPurify right before rendering; prefer Markdown rendered to safe output, or render structured data with normal templates.
- Content inserted by
v-htmlis not compiled by Vue (no directives, no components), and scoped styles do not apply to it without:deep(). - It replaces the element's children (
v-htmlwith children is a compile error), and it also renders raw during SSR. - Defence in depth: a Content Security Policy and server-side sanitization; the eslint-plugin-vue rule
vue/no-v-htmlflags every use.
Clarifying questions expected:
- "Where does the HTML come from: our own CMS, a Markdown editor, or arbitrary users?"
- "Which tags actually need to be supported?"
Code / implementation expected: Yes. Show the unsafe pattern, and a sanitized or alternative version.