{"id":2504,"date":"2019-12-02T07:30:30","date_gmt":"2019-12-02T15:30:30","guid":{"rendered":"https:\/\/blog.mozilla.org\/security\/?p=2504"},"modified":"2020-09-23T14:10:42","modified_gmt":"2020-09-23T21:10:42","slug":"help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/","title":{"rendered":"Help Test Firefox\u2019s built-in HTML Sanitizer to protect against UXSS bugs"},"content":{"rendered":"<div><\/div>\n<p>I recently gave a talk at OWASP Global AppSec in Amsterdam and summarized the presentation in a blog post about <a href=\"https:\/\/frederik-braun.com\/firefox-ui-xss-leading-to-rce.html\">how to achieve &#8220;critical&#8221;-rated code execution vulnerabilities in Firefox with user-interface XSS<\/a>. The end of that blog posts encourages the reader to participate the bug bounty program, but did not come with proper instructions. This blog post will describe the mitigations Firefox has in place to protect against XSS bugs and how to test them.<\/p>\n<p>Our about: pages are privileged pages that control the browser (e.g., <code>about:preferences<\/code>, which contains Firefox settings). A successful XSS exploit has to bypass <a href=\"https:\/\/blog.mozilla.org\/security\/2019\/10\/14\/hardening-firefox-against-injection-attacks\/\"><em>the Content Security Policy (CSP), which we have recently added <\/em><\/a>but also our built-in XSS sanitizer to gain arbitrary code execution. A bypass of the sanitizer without a CSP bypass is in itself a severe-enough security bug and warrants a bounty, subject to the discretion of the Bounty Committee. See the <a href=\"https:\/\/www.mozilla.org\/en-US\/security\/client-bug-bounty\/\"><em>bounty pag<\/em><\/a><a href=\"https:\/\/www.mozilla.org\/en-US\/security\/client-bug-bounty\/\"><em>es<\/em><\/a> for more information, including how to submit findings.<\/p>\n<h2>How the Sanitizer works<\/h2>\n<p>The Sanitizer runs in the so-called <a href=\"https:\/\/w3c.github.io\/DOM-Parsing\/#dfn-fragment-parsing-algorithm\"><em>&#8220;fragment parsing&#8221;<\/em><\/a> step of innerHTML. In more detail, whenever someone uses innerHTML (or similar functionality that parses a string from JavaScript into HTML) the browser builds a DOM tree data structure. Before the newly parsed structure is appended to the existing DOM element our sanitizer intervenes. This step ensures that our sanitizer can not mismatch the result the actual parser would have created &#8211; because it is indeed the actual parser.<\/p>\n<p>The line of code that triggers the sanitizer is in <a href=\"https:\/\/searchfox.org\/mozilla-central\/rev\/171109434c6f2fe086af3b2322839b346a112a99\/dom\/base\/nsContentUtils.cpp#4683\"><em>nsContentUtils::ParseFragmentHTML<\/em><\/a> and <em>nsContentUtils::ParseFragmentXML<\/em>. This aforementioned link points to a specific source code revision, to make hotlinking easier. Please click the file name at the top of the page to get to the newest revision of the source code.<\/p>\n<p>The sanitizer is implemented as an allow-list of elements, attributes and attribute values in <a href=\"https:\/\/searchfox.org\/mozilla-central\/source\/dom\/base\/nsTreeSanitizer.cpp\"><em>nsTreeSanitizer.cpp<\/em><\/a>. Please consult the allow-list before testing.<\/p>\n<p><strong>Finding a Sanitizer bypass is a hunt for <\/strong><a href=\"https:\/\/en.wikipedia.org\/wiki\/Cross-site_scripting#Mutated_XSS_(mXSS)\"><em><strong>Mutated XSS (mXSS)<\/strong><\/em><\/a><strong> bugs in Firefox<\/strong> \u2013 Unless you find an element in our allow-list that has recently become capable of running script.<\/p>\n<h2>How and where to test<\/h2>\n<p>A browser is a complicated application which consists of millions of lines of code. If you want to find new security issues, you should test the <a href=\"https:\/\/nightly.mozilla.org\/\"><em>latest development version<\/em><\/a>. We often times rewrite lots of code that isn&#8217;t related to the issue you are testing but might still have a side-effect. To make sure your bug is actually going to affect end users, test <a href=\"https:\/\/nightly.mozilla.org\/\"><em>Firefox Nightly<\/em><\/a>. Otherwise, the issues you find in Beta or Release might have already been fixed in Nightly.<\/p>\n<h2>Sanitizer runs in all privileged pages<\/h2>\n<p>Some of Firefox\u2019s internal pages have more privileges than regular web pages. For example about:config allows the user to modify advanced browser settings and hence relies on those expanded privileges.<\/p>\n<p>Just open a new tab and navigate to about:config. Because it has access to privileged APIs it can not use innerHTML (and related functionality like outerHTML and so on) without going through the sanitizer.<\/p>\n<h3>Using Developer Tools to emulate a vulnerability<\/h3>\n<p>From <code>about:config<\/code>, open The developer tools console (Go to <em>Tools<\/em> in the menu bar. Select <em>Web Developers<\/em>, then <em>Web Console<\/em> (Ctrl+Shift+k)).<\/p>\n<p>To emulate an XSS vulnerability, type this into the console:<\/p>\n<p><code>document.body.innerHTML = '&lt;img src=x onerror=alert(1)&gt;'<\/code><\/p>\n<p>Observe how Firefox sanitizes the HTML markup by looking at the error in the console:<\/p>\n<p><code>\u201cRemoved unsafe attribute. Element: img. Attribute: onerror.\u201d<\/code><\/p>\n<p>You may now go and try other variants of XSS against this sanitizer. Again, try finding an mXSS bug or by identifying an allowed combination of element and attribute which execute script.<\/p>\n<h3>Finding an actual XSS vulnerability<\/h3>\n<p>Right, so for now we have <em>emulated<\/em> the Cross-Site Scripting (XSS) vulnerability by typing in innerHTML ourselves in the Web Console. That&#8217;s pretty much cheating. But as I said above: <em>What we want to find are sanitizer bypasses. This is a call to test our mitigations.<\/em><\/p>\n<p>But if you still want to find real XSS bugs in Firefox, I recommend you run some sort of smart static analysis on the Firefox JavaScript code. And by smart, I probably do not mean <a href=\"https:\/\/github.com\/mozilla\/eslint-plugin-no-unsanitized\"><em>eslint-plugin-no-unsanitized<\/em><\/a>.<\/p>\n<h2>Summary<\/h2>\n<p>This blog post described the mitigations Firefox has in place to protect against XSS bugs. These bugs can lead to remote code execution outside of the sandbox. We encourage the wider community to double check our work and look for omissions. This should be particularly interesting for people with a web security background, who want to learn more about browser security. Finding severe security bugs is very rewarding and we\u2019re looking forward to getting some feedback. If you find something, please consult the <a href=\"https:\/\/www.mozilla.org\/en-US\/security\/bug-bounty\/\"><em>Bug Bounty pages<\/em><\/a> on how to report it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently gave a talk at OWASP Global AppSec in Amsterdam and summarized the presentation in a blog post about how to achieve &#8220;critical&#8221;-rated code execution vulnerabilities in Firefox with &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/\">Read more<\/a><\/p>\n","protected":false},"author":405,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[69],"tags":[45514,45498],"coauthors":[280726],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Help Test Firefox\u2019s built-in HTML Sanitizer to protect against UXSS bugs - Mozilla Security Blog<\/title>\n<meta name=\"description\" content=\"Tips for participants in our bug bounty program\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Frederik Braun\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/\",\"url\":\"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/\",\"name\":\"Help Test Firefox\u2019s built-in HTML Sanitizer to protect against UXSS bugs - Mozilla Security Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/#website\"},\"datePublished\":\"2019-12-02T15:30:30+00:00\",\"dateModified\":\"2020-09-23T21:10:42+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/9a9b6565cbac3c698b84dbd7447e438f\"},\"description\":\"Tips for participants in our bug bounty program\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/security\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Help Test Firefox\u2019s built-in HTML Sanitizer to protect against UXSS bugs\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/security\/\",\"name\":\"Mozilla Security Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/security\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/9a9b6565cbac3c698b84dbd7447e438f\",\"name\":\"Frederik Braun\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/image\/f188d5ece9062fd6ec08fbeb06809792\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/1f41f3ef916e1c1fc9401cf3212a6708?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/1f41f3ef916e1c1fc9401cf3212a6708?s=96&d=identicon&r=g\",\"caption\":\"Frederik Braun\"},\"description\":\"Frederik Braun defends Mozilla Firefox as a Staff Security Engineer in Berlin. He's also a member of the W3C Web Application Security Working Group and co-authored the Subresource Integrity standard.\",\"sameAs\":[\"https:\/\/frederik-braun.com\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Help Test Firefox\u2019s built-in HTML Sanitizer to protect against UXSS bugs - Mozilla Security Blog","description":"Tips for participants in our bug bounty program","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/","twitter_misc":{"Written by":"Frederik Braun","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/","url":"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/","name":"Help Test Firefox\u2019s built-in HTML Sanitizer to protect against UXSS bugs - Mozilla Security Blog","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/security\/#website"},"datePublished":"2019-12-02T15:30:30+00:00","dateModified":"2020-09-23T21:10:42+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/9a9b6565cbac3c698b84dbd7447e438f"},"description":"Tips for participants in our bug bounty program","breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/security\/2019\/12\/02\/help-test-firefoxs-built-in-html-sanitizer-to-protect-against-uxss-bugs\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/security\/"},{"@type":"ListItem","position":2,"name":"Help Test Firefox\u2019s built-in HTML Sanitizer to protect against UXSS bugs"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/security\/#website","url":"https:\/\/blog.mozilla.org\/security\/","name":"Mozilla Security Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/security\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/9a9b6565cbac3c698b84dbd7447e438f","name":"Frederik Braun","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/image\/f188d5ece9062fd6ec08fbeb06809792","url":"https:\/\/secure.gravatar.com\/avatar\/1f41f3ef916e1c1fc9401cf3212a6708?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1f41f3ef916e1c1fc9401cf3212a6708?s=96&d=identicon&r=g","caption":"Frederik Braun"},"description":"Frederik Braun defends Mozilla Firefox as a Staff Security Engineer in Berlin. He's also a member of the W3C Web Application Security Working Group and co-authored the Subresource Integrity standard.","sameAs":["https:\/\/frederik-braun.com"]}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts\/2504"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/users\/405"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/comments?post=2504"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts\/2504\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/media?parent=2504"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/categories?post=2504"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/tags?post=2504"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/coauthors?post=2504"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}