704: Sanitizer API with Frederik Braun
Episode
62 min
Read time
2 min
Topics
Leadership, Design & UX, Software Development
AI-Generated Summary
Key Takeaways
- ✓setHTML as innerHTML replacement: Replace `element.innerHTML` with `element.setHTML(input)` to get browser-guaranteed XSS-safe HTML insertion. The method uses the browser's own HTML parser, so sanitization stays current as HTML evolves. No configuration required for basic usage — the default safe list handles common elements automatically, making it a near-direct search-and-replace upgrade with zero security expertise needed.
- ✓setHTML vs setHTMLUnsafe: Two methods exist by design. `setHTML` cannot be configured to allow scripts under any circumstance — XSS safety is guaranteed. `setHTMLUnsafe` mirrors React's "dangerously set inner HTML" naming pattern, signaling developer intent. Frederik Braun recommends only using the unsafe variant if a security engineer is actively involved in reviewing the configuration and its implications.
- ✓Allowlist configuration over blocklist: Rather than removing unwanted elements, configure a `new Sanitizer()` with an explicit `elements` array listing only what your use case requires — paragraph, anchor, bold, italic, blockquote, lists. This approach stays evergreen: future HTML elements are automatically excluded. Custom web components with dash-separated names like `dave-card` can be explicitly added to the allowlist by name.
- ✓Defense-in-depth with server-side sanitization: Server-side sanitization and `setHTML` serve complementary roles. Backend libraries sanitize on intake, but browser-side sanitization handles mismatches between server assumptions and the specific browser rendering the page. Academic research confirms that sanitizers outside the browser frequently fail on edge cases — malformed HTML, browser-specific parsing quirks, and newly introduced elements that backend libraries haven't yet catalogued.
- ✓CSP + Trusted Types integration: Content Security Policy's Trusted Types feature can be set to reject all `innerHTML`, `document.write`, `outerHTML`, and `insertAdjacentHTML` calls at runtime via a single HTTP header configuration. Combined with `setHTML`, this creates a hard enforcement layer where unsafe DOM manipulation throws errors rather than silently executing. Despite CSP existing since roughly 2010, over 80% of pages using it still lack sufficient XSS protection.
What It Covers
Frederik Braun, manager of Firefox application security at Mozilla, explains the newly shipped Sanitizer API — a browser-native solution to cross-site scripting (XSS). The episode covers `setHTML` vs `innerHTML`, sanitizer configuration with allowlists, integration with Content Security Policy, DOMPurify's role, and how the API handles custom elements and data attributes.
Key Questions Answered
- •setHTML as innerHTML replacement: Replace `element.innerHTML` with `element.setHTML(input)` to get browser-guaranteed XSS-safe HTML insertion. The method uses the browser's own HTML parser, so sanitization stays current as HTML evolves. No configuration required for basic usage — the default safe list handles common elements automatically, making it a near-direct search-and-replace upgrade with zero security expertise needed.
- •setHTML vs setHTMLUnsafe: Two methods exist by design. `setHTML` cannot be configured to allow scripts under any circumstance — XSS safety is guaranteed. `setHTMLUnsafe` mirrors React's "dangerously set inner HTML" naming pattern, signaling developer intent. Frederik Braun recommends only using the unsafe variant if a security engineer is actively involved in reviewing the configuration and its implications.
- •Allowlist configuration over blocklist: Rather than removing unwanted elements, configure a `new Sanitizer()` with an explicit `elements` array listing only what your use case requires — paragraph, anchor, bold, italic, blockquote, lists. This approach stays evergreen: future HTML elements are automatically excluded. Custom web components with dash-separated names like `dave-card` can be explicitly added to the allowlist by name.
- •Defense-in-depth with server-side sanitization: Server-side sanitization and `setHTML` serve complementary roles. Backend libraries sanitize on intake, but browser-side sanitization handles mismatches between server assumptions and the specific browser rendering the page. Academic research confirms that sanitizers outside the browser frequently fail on edge cases — malformed HTML, browser-specific parsing quirks, and newly introduced elements that backend libraries haven't yet catalogued.
- •CSP + Trusted Types integration: Content Security Policy's Trusted Types feature can be set to reject all `innerHTML`, `document.write`, `outerHTML`, and `insertAdjacentHTML` calls at runtime via a single HTTP header configuration. Combined with `setHTML`, this creates a hard enforcement layer where unsafe DOM manipulation throws errors rather than silently executing. Despite CSP existing since roughly 2010, over 80% of pages using it still lack sufficient XSS protection.
- •DOMPurify as the current fallback: For browsers not yet supporting the Sanitizer API, DOMPurify remains the recommended library — its author Mario Heiderich co-authored the Sanitizer API specification. DOMPurify weighs approximately 8.3KB gzipped. The progressive enhancement pattern is: check `if (window.Sanitizer)`, use `setHTML` if available, otherwise fall back to DOMPurify plus `innerHTML`. Firefox shipped the API first; Chrome support was imminent at recording time.
Notable Moment
Frederik Braun notes that cross-site scripting remains one of the top three most reported vulnerabilities in the US National Vulnerability Database — despite Content Security Policy existing for roughly fifteen years. The implication is that technically sound solutions fail without adoption simplicity, which is precisely the problem `setHTML` is designed to solve.
Episode Transcript
Hey, there's somebody who may actually listen to another episode of the ShopTalk Show. I'm Dave XSS Rupert. With me is Chris drop tables coir. Hey, Chris. How are you doing today? Good. Feeling X especially good. Or something. Yeah. Was that was that of Dave quality? Yes, sir. I don't know. I'm the I'm out of security tip. This is a very, specific and special episode where we're gonna be specifically talking about, web security and, you know, basically, the sanitizer API because it's new and it's cool. And we have somebody who's it's very near and dear to Frederick Braun. Welcome to the show. Thanks for coming on. Hi. Yeah. Thanks for having me. Sure. You are at Mozilla. Right? Yes. I manage the Firefox application security team and Oh. Like to do engineering stuff like web security APIs from time to time. The president of web security is with us today. That's great. Lovely and good timing as we're recording this. This just dropped in Firefox a couple of days ago. So we're talking about brand new API stuff. Kinda cool to see security stuff be addressed front and center. In this day and age, it is literally called the sanitizer API. Right? Kind of, an exciting thing. What what is it? The idea is when anywhere in your web application you take untrusted input, like HTML Mhmm. And you want to bring this into the document, let's say, user comments, third party databases that you're talking to, some other APIs, you can't really rely on them to be safe for your document because of cross site scripting, script injections, but also other things that may mess with your markup. That's exactly what I think of. You know, you got a website, and and and you have a blog post at the bottom or whatever. At the bottom of it, there's a text area, and somebody types in there, like, hey. Great comment. I suggest something, you know, that looks looks benign, a healthy little comment. And at the bottom, they write script, source evil website, something like x s or or a script tag that tries to send your cookies somewhere or whatever. This is classic XSS. You'll see it. A lot of times, people use the alert function, which doesn't alert is not dangerous. It's just proof. It's a little Yeah. Exactly. Classic way to prove that you can run untrusted JavaScript. And so there's been ways to, to deal with this in the past, but now we have new ways. Keep going. Yeah. So the idea is when you want to have more specific control rather than disallow, you want to filter HTML. And while in theory, you could build your own for loop that iterates over all of the nodes and then looks at, I don't know, attribute names and elements and so on, you don't really want to make that decision by yourself, what is safe, what isn't, given that browsers are …
Get the full transcript (10,721 words) + summary by email — free
One-time email with the complete transcript and AI summary of this episode. No account needed.
One email, no spam. We’ll also show you what SignalCast does.
You just read a 3-minute summary of a 59-minute episode.
Get Shop Talk Show summarized like this every Monday — plus up to 2 more podcasts, free.
Pick Your Podcasts — FreeKeep Reading
More from Shop Talk Show
731: Terminal UX, Running Multiple Services, Don’t Settle for an App
Sep 7 · 58 min
How I AI
How Claude Mythos found a 15-year-old bug in Mozilla Firefox | Brian Grinstead
Jun 22
More from Shop Talk Show
730: A/B Testing with Charts, Music Recommendations, & Web Permissions
Aug 31 · 60 min
The Product Experience
Lessons from Firefox and Twitter - Alan Byrne (Product Leader, Mozilla)
Feb 18
Books, tools, and gear mentioned in this episode
SignalCast may earn commission on purchases via these links.
Tools
“Content Security Policy's Trusted Types feature can be set to reject all `innerHTML`, `document.write`, `outerHTML`, and `insertAdjacentHTML` calls at runtime via a single HTTP header configuration.”
- Sanitizer APIRecommended
“Frederik Braun, manager of Firefox application security at Mozilla, explains the newly shipped Sanitizer API — a browser-native solution to cross-site scripting (XSS).”
- DOMPurifyRecommended
by Mario Heiderich
“For browsers not yet supporting the Sanitizer API, DOMPurify remains the recommended library — its author Mario Heiderich co-authored the Sanitizer API specification. DOMPurify weighs approximately 8.3KB gzipped.”
More from Shop Talk Show
We summarize every new episode. Want them in your inbox?
731: Terminal UX, Running Multiple Services, Don’t Settle for an App
730: A/B Testing with Charts, Music Recommendations, & Web Permissions
729: After Dark Edition! Microlighter, Tri-state Drama, and Editing Video Quickly
728: BIMI, Good Favicon Practice, and CSS @Layer Exploration
727: Front-End Complexity, AI Co-Authorship, and New CSS Navigation Patterns
Similar Episodes
Related episodes from other podcasts
How I AI
Jun 22
How Claude Mythos found a 15-year-old bug in Mozilla Firefox | Brian Grinstead
The Product Experience
Feb 18
Lessons from Firefox and Twitter - Alan Byrne (Product Leader, Mozilla)
Eye on AI
Feb 1
#319 Subho Halder: Why Traditional App Security Fails in the Age of AI
Cognitive Revolution
Jan 25
The Internet Computer: Caffeine.ai CEO Dominic Williams on Unstoppable, Self-Writing Software
The Rework Podcast
Jan 21
AI Revisited
Explore Related Topics
This podcast is featured in Best Cybersecurity Podcasts (2026) — ranked and reviewed with AI summaries.
Read this week's Software Engineering Podcast Insights — cross-podcast analysis updated weekly.
You're clearly into Shop Talk Show.
Every Monday, we deliver AI summaries of the latest episodes from Shop Talk Show and 192+ other podcasts. Free for one show.
Start My Monday DigestNo credit card · Unsubscribe anytime