What is mutation XSS (mXSS)?
mXSS is a new type of XSS attack by Mario Heiderich. I actually saw him present this very talk at Syscan 2013 this year.
The vulnerability in question comes from innerHTML which allows direct manipulation of HTML content, bypassing the DOM. An elements innerHTML is non-idempotent. The browser manipulates the contents to fix and optimize errors with the HTML. This is very visible in the example given in the slides. The problem with this manipulation is that it sometimes introduces flaws that is not apparent at first sight. One good example is also in the slides.
The big deal about this attack is that it bypasses (at the time of the talk, situation may be better now) most of the existing XSS filters and sanitizers.
As far as I know, there isn't any other available information about this class of XSS attack besides whatever information is present in the presentation slides.
This is a kind of an ancient post, but some comments were asking if there was any defense.
Here's an excerpt from the paper:
At this point the string is still harmless and cannoot be used to execute an XSS attack. However, as soon as this string is inserted into the browser's DOM by using the
innerHTML
property, the browser will mutate the string. This mutation is highly unpredictable since it is not part of the specifiedinnerHTML
handling, but is a proprietary optimization of HTML code implemented differently in each of the main browser families. The mutated string now contains a valid XSS vector, and the attack will be executed on rendering the new DOM element. Both Server and client filters were unable to detect this attack because the string scanned in these filters did not contain any executable code.
This exploit is actually a BROWSER-BASED exploit. And in the world of rather dynamic frameworks like angularjs and jquery, there's quite a bit of innerHTML
going on under the hood, even in 2012-2013 when this attack was first described.
The author goes on to say:
If
innerHTML
is only used to insert trusted code from the webapplication itself into the DOM, it is not vulnerable.
So the answer to "is there anything we can do?" is: Don't use innerHTML
in combination with user input.
But wait... what if my application has thousands of calls to innerHTML
or we use jquery? The paper discusses a script they offered called "TrueHTML." When looking for example code, the best I was able to find was here, where you override the client's use of innerHTML
, bypassing the functions discussed in the original attack... and without needing to do more than to add a single script file. The paper also discusses a minimal performance hit.
(I'm not 100% sure if the code listing I used ought to be trusted--I didn't write it, copy-pasta at your own risk! That said, it appears to use the technique described in the paper.) I'm not sure if the "isExploitable" check returns a proper value.
Here's an excerpt from the provided github commit:
mitigateMXSS: function (element) {
+ var that = this;
+ if (typeof element.innerHTML === 'string') {
+ Object.defineProperty(element, 'innerHTML', {
+ get: function () { return that.changeInnerHtmlHandler(this, 'innerHTML') },
+ set: function (html) {
+ while (this.firstChild) {
+ this.removeChild(this.lastChild);
+ }
+ this.insertAdjacentHTML('afterBegin', html);
+ }
+ });
+ }
+ },