[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 <script>. 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)