[HN Gopher] Element: setHTML() method
       ___________________________________________________________________
        
       Element: setHTML() method
        
       Author : todsacerdoti
       Score  : 82 points
       Date   : 2025-10-22 09:03 UTC (13 hours ago)
        
 (HTM) web link (developer.mozilla.org)
 (TXT) w3m dump (developer.mozilla.org)
        
       | michalpleban wrote:
       | So is this basically a safe version of innerHTML?
        
         | Octoth0rpe wrote:
         | Yes, although a slightly more relevant way of putting it would
         | be that it's an inbuilt DOMPurify (dompurify being an npm
         | package commonly used to sanitize html before injecting it).
        
       | evilpie wrote:
       | We enabled this by default in Firefox Nightly (only) this week.
        
         | spankalee wrote:
         | I'll be very excited to use this in Lit when it hits baseline.
         | 
         | While lit-html templates are already XSS-hardened because
         | template strings aren't forgeable, we do have utilities like
         | `unsafeHTML()` that let you treat untrusted strings as HTML,
         | which are currently... unsafe.
         | 
         | With `Element.setHTML()` we can make a `safeHTML()` directive
         | and let the developer specify sanitizer options too.
        
           | StrauXX wrote:
           | Why don't you use DOMPurify right now? It's battle tested and
           | supports configs just like this proposal.
        
       | redbell wrote:
       | > This feature is not Baseline because it does not work in some
       | of the most widely-used browsers.
       | 
       | This is interesting, but it appears to be in its early days as
       | _none_ of the major browsers seem to support it.. yet.
        
         | JadeNB wrote:
         | A sibling comment by evilpie says that it is enabled in Firefox
         | Nightly: https://news.ycombinator.com/item?id=45674985
        
       | CaptainOfCoit wrote:
       | Really happy to see it, after 25 years
       | (https://www.bugcrowd.com/glossary/cross-site-scripting-xss/) of
       | surviving without it. It always struck me as an obvious missing
       | part of the DOM API, and I still don't know why it took this long
       | time.
       | 
       | But mostly I'm just happy that it's finally here, I do appreciate
       | all the hard work people been doing to get this live.
        
       | AlienRobot wrote:
       | Great functionality, terrible name.
        
         | varun_ch wrote:
         | I sometimes wonder whether what the DOM APIs could look like in
         | a hypothetical world where we could start over with everything.
        
         | jonathrg wrote:
         | Why? Does it not set the HTML?
        
       | dzogchen wrote:
       | Neat. I think once this is adopted by HTMX (or similar libraries)
       | you don't need to sanitize on the server side anymore?
        
         | dylan604 wrote:
         | Do you honestly feel that we will ever be in a place for the
         | server to not need to sanitize data from the client? Really? I
         | don't. Any suggestion to me of "not needing to sanitize data
         | from client" will immediately have me thinking the person doing
         | the suggesting is not very good at their job, really new, or
         | trying to scam me.
         | 
         | There's no reason to _not_ sanitize data from the client, yet
         | every reason _to_ sanitize it.
        
           | jsmith99 wrote:
           | It's arguably easier just to sanitise at display time
           | otherwise you have problems like double escaping.
        
             | bpt3 wrote:
             | Easier does not mean better, which seems to be true in this
             | case given the many, many vulnerabilities that have been
             | exploited over the years due to a lack of input
             | sanitization.
        
               | padjo wrote:
               | In this case easier is actually better. Sanitize a string
               | at the point where you are going to use it. The locality
               | makes it easy to verify that sanitation has been done
               | correctly for the context. The alternative means you have
               | to maintain a chain of custody for the string and ensure
               | it is safe.
        
           | strbean wrote:
           | It can be a complicated and error-prone process, mainly in
           | scenarios where you have multiple mediums that require
           | different sanitizers. Obviously you should do it. But in such
           | scenarios, the best practice is to sanitize as close to the
           | place it is used as possible. I've seen terrible codebases
           | where they tried to apply multiple layers of sanitization on
           | user input before storing to the DB, then reverse the
           | unneeded layers before output. Obviously this didn't work.
           | 
           | Point being, if you can move sanitization _even closer_ to
           | where it is used, and that sanitization is actually provided
           | by the standard library of the platform in question, that 's
           | a massive win.
        
             | immibis wrote:
             | By "sanitise" what's really meant is usually "escape". User
             | typed their display name as <script>. You want the screen
             | to say their display name, which is <script>. Therefore you
             | send &lt;script&gt;. That's not their display name - that's
             | just what you write in HTML to get their display name to
             | appear on the screen. You shouldn't store it in the
             | database in the display_name column.
        
               | strbean wrote:
               | Agreed. The codebase I'm thinking of was html encoding
               | stuff before storing it, then when they needed to e.g.
               | send an SMS, trying to remember to decode. Terrible.
        
           | padjo wrote:
           | Sanitize as close as possible to where it is used is usually
           | best, then you don't have to keep track of what's sanitized
           | and what's not sanitized for very long.
           | 
           | (Especially important if sanitation is not idempotent!)
        
       | ishouldbework wrote:
       | > It then removes any HTML entities that aren't allowed by the
       | sanitizer configuration, and further removes any XSS-unsafe
       | elements or attributes -- _whether or not they are allowed by the
       | sanitizer configuration_.
       | 
       | Emphasis mine. I do not understand this design choice. If I
       | explicitly allow `script` tag, why should it be stripped?
       | 
       | If the method was called setXSSSafeSubsetOfHTML sure I guess, but
       | feels weird for _setHTML_ to have impossible-to-override filter.
        
         | evilpie wrote:
         | If you want to use an XSS-unsafe Sanitizer you have to use
         | setHTMLUnsafe.
        
         | jmull wrote:
         | I guess they are going for a safe default... the idea is people
         | who don't carefully read the docs or carefully monitor the
         | provenance of their dynamically generated HTML will probably
         | reach for "setHTML()".
         | 
         | Meanwhile, there's "setHTMLUnsafe()" and, of course, good old
         | .innerHTML.
        
         | strbean wrote:
         | This is primarily an ergonomic addition, so it kinda makes
         | sense to me to not make the dangerous footguns more ergonomic
         | in the process. You can still assign `innerHTML` etc. to do the
         | dangerous thing.
        
           | hsbauauvhabzb wrote:
           | Ideally this should be called dangerouslySetInnerHTML but
           | hindsight blah blah
        
           | meowface wrote:
           | I agree, though I also agree with the parent that the method
           | name is a little bit confusing. "safeSetHTML" or
           | "setUntrustedHTML" or something would be clearer.
        
             | strbean wrote:
             | Idk about that, there's a good argument that the most
             | obvious methods should be the safe ones. That's what
             | juniors will probably jump to first. If you need the unsafe
             | ones, you'll probably be able to figure that out and find
             | them quickly.
        
         | wewtyflakes wrote:
         | Wouldn't that open the floodgates by allowing code that could
         | itself call `setHTML` again but then further revise the args to
         | escalate its privileges?
        
       | ibowankenobi wrote:
       | The API design could be better. Document fragments are designed
       | to be reused. It should accept an optional fragment key which
       | accepts a document fragment.If not a fragment, throw, if has
       | children, empty contents first.
        
         | spankalee wrote:
         | In what way are document fragments meant to be reused?
         | 
         | They empty their contents into the new parent when they're
         | appended, so they can't be meaningfully appended a second time
         | without rebuilding them.
         | 
         | `<template>` is mean to be reused, since you're meant to clone
         | it in order to use it, and then you can clone it again.
        
       | padjo wrote:
       | As someone who has dealt with more than my fair share of content
       | injection vulnerabilities over the years this is great to see at
       | last. It's kinda crazy that this only coming now while other,
       | more cumbersome solutions like CSP have been around for years.
        
       | modinfo wrote:
       | Cursor build a pseudo-sethtml:
       | https://github.com/skorotkiewicz/pseudo-sethtml
        
       | _the_inflator wrote:
       | Maybe it is then time for having something that is beyond "use
       | strict" at the beginning auf a JavaScript document as one option
       | to use the statement.
       | 
       | I think a config object in which you define for script options
       | like sanitization and other script configuration might be
       | helpful.
       | 
       | After all, there almost always need to be backward compatibility
       | be ensured, and this might work. I am no spec guy, it is just an
       | idea. React makes use of "use client/server", so this would be
       | more central and explicit.
        
       ___________________________________________________________________
       (page generated 2025-10-22 23:00 UTC)