<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body
 bgcolor="#FFFFFF" text="#000000">



  <span style="font-style: italic;">tl;dr Raw markup injection (e.g. 
through innerHTML) in system-privileged content is automatically 
sanitized and we have removed all exceptions to this rule. You should 
still not use innerHTML and friends.</span><br>


  <br>


Hello everyone,<br>


  <br>


The danger of remote code execution (RCE) exploits through unescaped 
innerHTML usage was recently brought to renewed public attention <a 
href="https://thehackerblog.com/i-too-like-to-live-dangerously-accidentally-finding-rce-in-signal-desktop-via-html-injection-in-quoted-replies/index.html">through


 the finding of a spectacular vulnerability in the Signal Desktop app</a>.
 As most of you know, the Firefox front-end, like Signal, is written 
using web technologies, which means that innerHTML and similar 
techniques of injecting raw markup are a constant threat to us as well.<br>


  <br>


An injection vulnerability in system privileged desktop UI can safely be
 considered a worst-case scenario. Once found, it is usually very easy 
to exploit and grants the attacker full system privileges without 
requiring a sandbox escape. The Firefox Security Engineering team 
identified this threat some time ago and we have been making slow but 
constant progress towards a solution.<br>


  <br>


  <span style="font-weight: bold;">Today, I'm happy to announce that 
there is not a single instance of potentially unsafe innerHTML usage in 
system-privileged Firefox code.</span><br>


  <br>


How can I be sure?<br>


  <br>


We started <a 
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1432966">sanitizing 
system privileged innerHTML assignments at the platform level</a>. The 
Sanitizer will drop (remove) any nodes or attributes from the supplied 
markup that are considered unsafe. (See <a 
href="https://searchfox.org/mozilla-central/rev/83a923ef7a3b95a516f240a6810c20664b1e0ac9/dom/base/nsContentUtils.cpp#5086">this


 code</a> and <a 
href="https://searchfox.org/mozilla-central/rev/83a923ef7a3b95a516f240a6810c20664b1e0ac9/dom/base/nsTreeSanitizer.h#48">that


 code</a>) It will also log a warning about it. The initial patch had 
enough breakage that it forced us to add an exception to this rule, in 
the form of a function called unsafeSetInnerHTML, which could be called 
in place of innerHTML assignment.<br>


  <br>


During the last months we have been working on removing this function 
again, fixing up the individual callers with safe alternatives. The 
devtools team recently (heroically) removed the GCLI UI (and is working 
to replace some of its most popular features) to support this effort.<br>


  <br>


Yesterday we landed patches to <a 
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1444394">remove 
unsafeSetInnerHTML</a> again, leaving no way to bypass sanitization in 
chrome code.<br>


  <br>


Note that, for obvious reasons, we will not be able to have sanitization
 in regular content-privileged contexts. This is one reason why we still
 run an ESLint plugin called <a 
href="https://github.com/mozilla/eslint-plugin-no-unsanitized">eslint-plugin-no-unsanitized</a>
 that will call out any potentially unsafe usage of innerHTML. Please be
 extra cautious around old code that is highlighted with an exception to
 that lint and please, do not introduce new exceptions.<br>


  <br>


  <span style="font-style: italic; font-weight: bold;">So, can we use 
more innerHTML now?</span><br>


  <br>


  <span style="font-weight: bold;">NO. Please do not use innerHTML, even
 for the simplest use cases</span>. The sanitization only prevents the 
worst category of attacks and user input could still mess with the 
display or even behavior of your UI. It's also not very performant and 
you are running the risk of eventually moving it into content-privileged
 code, which is not sanitized.<br>


  <br>


  <span style="font-style: italic; font-weight: bold;">What if I know 
how to sanitize this stuff?</span><br>


  <br>


Experience tells us that while most developers understand that 
"node.innerHTML = userProvidedData" is bad, that's not necessarily how 
these vulnerabilities get introduced. The more your code gets moved or 
refactored the higher the risk of making it vulnerable along the way, 
even if your originally added innerHTML in a safe manner. We have seen 
vulnerabilities which were introduced through a series of refactorings, 
none of which actually touched the eventual innerHTML assignment.<br>


  <br>


Don't roll your own innerHTML sanitization, please. Someone else will 
break it.<br>


  <br>


Thank you to all the great people who made this possible (in no 
particular order):<br>


  <br>


Boris Zbarsky, Mike Conley, J. Ryan Stinnet,  Andrew Swan, Gijs 
Kruitbosch, Prathiksha, Trisha Gupta, Jorg K, Mark Striemer, Dan Veditz,
 Nihanth Subramanya, Wennie Leung<br>


  <br>


And a special thanks to:<br>


  <br>


Frederik Braun, for being the author of eslint-plugin-no-unsanitized 
(and first to recognize this problem) and for all his general counsel.<br>


Kris Maglione, for coming up with the original sanitization plan.<br>


Joe Walker, Patrick Brosset, Soledad Penades and Alexandre Poirot, for 
removing GCLI.<br>


  <br>


Please let me know if you have any other questions or concerns.<br>


  <br>


Keep on rocking the free <img src="" onerror="alert('Web')" />,<br>


  <br>


Johann
</body>
</html>