This kind of thing always makes me nervous, because you end with a mix of methods where you can (supposedly) pass arbitrary user input to them and they'll safely handle it, and methods where you can't do that without introducing vulnerabilities - but it's not at all clear which is which from the names. Ideally you design that in from the state, so any dangerous functions are very clearly dangerous from the name. But you can't easily do that down the line.
I'm also rather sceptical of things that "sanitise" HTML, both because there's a long history of them having holes, and because it's not immediately clear what that means, and what exactly is considered "safe".
show comments
simonw
Great to see this start to show up, but it looks like it will be a while before browser support is widely distributed enough to rely on it being present: https://caniuse.com/mdn-api_element_sethtml
show comments
Aachen
So you can still inject <h1> or <br><br><br>...
etc into your username, in the given example
Preventing one bug class (script execution) is good, but this still allows arbitrary markup to the page (even <style> CSS rules) if I'm reading the docs correctly. You could give Paypal a fresh look for anyone who opens your profile page, if they use this. Who would ever want this?
show comments
jjcm
What I really want is a <sandbox> element that can safely run dangerous code, not something that modifies dangerous code.
Iframes have significant restrictions as they can’t flow with the DOM. With AI and the increase in dynamic content, there’s going to be even more situations where you run untrusted code. I want configurable encapsulation.
dogtimeimmortal
Title was a bit rage-baity. And I think you can already do sanitation by writing a function to check input before passing it to innerHTML?
This really just seems like another attempt at reinventing the wheel. Somewhat related, I find it ironic how i cannot browse hacks.mozilla.org in my old version of firefox("Browser not supported"). Also, developer.mozilla.org loads mangled to various degrees in current versions of palemoon, basilisk, and seamonkey
It's like there is some sort of "browser cartel" trying to screw up The Web.
show comments
cogman10
Seems like this has a bunch of footguns. Particularly if you interact with the Sanitizer api, and particularly if you use the "remove" sanitizer api.
Don't get me wrong, better than nothing, but also really really consider just using "setText" instead and never allow the user to add any sort of HTML too the document.
I don’t ever use it with user input, but use it often when building SPA without frameworks
tuyiown
This is nice. The best part is that all aspects of network access are now properly controlled so that security transitioned from a chain of trusted code to a chain of trusted security setup on hosts, with existing workable safe defaults.
kevincloudsec
naming the old behavior setHTMLUnsafe is what did it for me. security features that require developers to opt in don't work. making the unsafe path feel unsafe does.
shevy-java
Well, the name SetHTML, or let's say:
.set_html()
Makes objectively more sense than:
.inner_html()
.inner_html =
.set_inner_html()
It is a fairly small thing, but ... really. One day someone should clean up the mess that is JavaScript. Guess it will never happen, but JavaScript has so many strange things ...
I understand that this here is about protection against attacks rather than a better API design, but really - APIs should ideally be as great as possible the moment they are introduced and shown to the public.
show comments
pier25
Tangential but it's amazing in 2026 browsers still don't ship a native DOM morph/merge API like morphdom or idiomorph.
dvh
Kids in the '90s:
SQL("select * from user where name = " + name);
Kids in the '20s:
div.innerHTML = "Hello " + user.name;
show comments
austin-cheney
Another solution is just use this at the start of your code:
delete Element.prototype.innerHTML;
Then assignments to innerHTML do not modify the element's textContent or child node list and assignments to it will not throw an error.
bryanrasmussen
is there any situation where innerHTML would be preferable? I could suppose it might be more performant and so if you were constructing something that was not open to XSS it might theoretically be better (with the usual caveat that people always make mistakes about this kind of thing)
dbvn
at what point can we consider the development of "set this element's text/html" to be done?
show comments
antonyh
A rather deceptive title, given that 'innerHTML' isn't going away.
show comments
bingemaker
Nice one. Will there be any impact on __dangerouslySetInnerHTML (React)?
shadowgovt
Oh, that's nice-to-have. Good work, Mozilla.
It would close the loop better if you could also use policy to switch off innerHTML in a given page, but definitely a step in the right direction for plain-JavaScript applications.
giancarlostoro
My corporate firewall blocks it due to the "hacks" in the subdomain / url. This is silly.
This kind of thing always makes me nervous, because you end with a mix of methods where you can (supposedly) pass arbitrary user input to them and they'll safely handle it, and methods where you can't do that without introducing vulnerabilities - but it's not at all clear which is which from the names. Ideally you design that in from the state, so any dangerous functions are very clearly dangerous from the name. But you can't easily do that down the line.
I'm also rather sceptical of things that "sanitise" HTML, both because there's a long history of them having holes, and because it's not immediately clear what that means, and what exactly is considered "safe".
Great to see this start to show up, but it looks like it will be a while before browser support is widely distributed enough to rely on it being present: https://caniuse.com/mdn-api_element_sethtml
So you can still inject <h1> or <br><br><br>... etc into your username, in the given example
Preventing one bug class (script execution) is good, but this still allows arbitrary markup to the page (even <style> CSS rules) if I'm reading the docs correctly. You could give Paypal a fresh look for anyone who opens your profile page, if they use this. Who would ever want this?
What I really want is a <sandbox> element that can safely run dangerous code, not something that modifies dangerous code.
Iframes have significant restrictions as they can’t flow with the DOM. With AI and the increase in dynamic content, there’s going to be even more situations where you run untrusted code. I want configurable encapsulation.
Title was a bit rage-baity. And I think you can already do sanitation by writing a function to check input before passing it to innerHTML?
This really just seems like another attempt at reinventing the wheel. Somewhat related, I find it ironic how i cannot browse hacks.mozilla.org in my old version of firefox("Browser not supported"). Also, developer.mozilla.org loads mangled to various degrees in current versions of palemoon, basilisk, and seamonkey
It's like there is some sort of "browser cartel" trying to screw up The Web.
Seems like this has a bunch of footguns. Particularly if you interact with the Sanitizer api, and particularly if you use the "remove" sanitizer api.
Don't get me wrong, better than nothing, but also really really consider just using "setText" instead and never allow the user to add any sort of HTML too the document.
And for those who want a better innerHTML, use insertAdjacentHTML https://developer.mozilla.org/en-US/docs/Web/API/Element/ins...
I don’t ever use it with user input, but use it often when building SPA without frameworks
This is nice. The best part is that all aspects of network access are now properly controlled so that security transitioned from a chain of trusted code to a chain of trusted security setup on hosts, with existing workable safe defaults.
naming the old behavior setHTMLUnsafe is what did it for me. security features that require developers to opt in don't work. making the unsafe path feel unsafe does.
Well, the name SetHTML, or let's say:
Makes objectively more sense than: It is a fairly small thing, but ... really. One day someone should clean up the mess that is JavaScript. Guess it will never happen, but JavaScript has so many strange things ...I understand that this here is about protection against attacks rather than a better API design, but really - APIs should ideally be as great as possible the moment they are introduced and shown to the public.
Tangential but it's amazing in 2026 browsers still don't ship a native DOM morph/merge API like morphdom or idiomorph.
Kids in the '90s:
Kids in the '20s:Another solution is just use this at the start of your code:
Then assignments to innerHTML do not modify the element's textContent or child node list and assignments to it will not throw an error.is there any situation where innerHTML would be preferable? I could suppose it might be more performant and so if you were constructing something that was not open to XSS it might theoretically be better (with the usual caveat that people always make mistakes about this kind of thing)
at what point can we consider the development of "set this element's text/html" to be done?
A rather deceptive title, given that 'innerHTML' isn't going away.
Nice one. Will there be any impact on __dangerouslySetInnerHTML (React)?
Oh, that's nice-to-have. Good work, Mozilla.
It would close the loop better if you could also use policy to switch off innerHTML in a given page, but definitely a step in the right direction for plain-JavaScript applications.
My corporate firewall blocks it due to the "hacks" in the subdomain / url. This is silly.