How Firefox gives special permissions to some domains

Today, I found someone tweeting about a neat security bug in Chrome, that bypasses how Chrome disallows extensions from injecting JavaScript into special domains like chrome.google.com. The intention of this block is that browsers give special permissions to some internal pages that allow troubleshooting, resetting the browser, installing extensions and more.

The bug in question was an easy bypass of a domain block list due to a DNS trick. Due to a strict host name match, an attacker could extend the current hostname with a trailing dot to chrome.google.com. and bypass the block.

I believe, this allowed all extensions that can inject content scripts into arbitrary domains to potentially make use of these extra privileges.

Of course, this got me thinking. What if we have this bug in Firefox too? So I went on and looked at our code. Fortunately, I have been playing with our permission system for quite a while already, so I knew what to do.

First of all, Firefox uses a so-called PermissionManager API, which gets its default values from the file browser/app/permissions in the source tree. At the time of writing this article, the four different possible permissions are uitour, install, remote-troubleshooting and autoplay-media. So far, I have only looked into the first two, as I know how they work and what they do. But for the purpose of this analysis, and due to all of them going throgh the PermissionManager, I am relatively confident that testing two of those should verify the behavior of the API in itself - regardless of the specific permissions and sites involved.

The install permission is used on addons.mozilla.org to allow the website to trigger the installation of Firefox extensions. In fact, you can test that this is the case by navigating to addons.mozilla.org and looking at the exposed interfaces: typeof AddonManager returns "function". However, on any other web page, the result of that expression is undefined.

Now that we know how to test whether a page has the install permission, we can open tab that goes to addons.mozilla.org. and do the same again. What's typeof AddonManager here? undefined. No dice.

Let's continue with the uitour permission. The uitour permission is used in Firefox's new tab, support and download pages. It is used to invoke functionality from the user interface. When a Firefox user is being presented new features after a major upgrade, the uitour events can highlight Firefox menu buttons or open popups that contain new funcionality.

A specific example that I remember is that for example, when a Firefox user tries to download a new Firefox package, we assume that they are confused or dissatisfied with how their browser is setup right now. So instead of offering a download file, we also suggest "refreshing" Firefox, which can help undo some undesired customizations without losing stored passwords and such.

The code that you can run to try the uitour feature on www.mozilla.org is as such:

document.dispatchEvent(new CustomEvent('mozUITour', {
    bubbles: true,
    detail: {
        action: 'resetFirefox',
        data: {
        }
    }
}));

Dispatching this event will get you a new impressive modal dialog that asks the user if they really want to refresh Firefox.

Now that we have a test for the uitour feature, we can do the same thing we tried last time: Add a trailing dot and try again.

Going to www.mozilla.org. and trying again yields similar results as above: No prompt shows.

To summarize: Our quick analysis has shown that even if we could get the web extension code to be confused about whether a page should be scripted. The permission manager does not play along.

I think we can safely assume that Firefox is not affected by the same bug. But you shouldn't take my word for it. Feel free to prove me wrong: Here are some links to our code:

If you feel like you have found something that I did not, please submit to the Firefox bug bounty program.


If you find a mistake in this article, you can submit a pull request on GitHub.

Other posts

  1. How Firefox gives special permissions to some domains (Fri 02 February 2024)
  2. Examine Firefox Inter-Process Communication using JavaScript in 2023 (Mon 17 April 2023)
  3. Origins, Sites and other Terminologies (Sat 14 January 2023)
  4. Finding and Fixing DOM-based XSS with Static Analysis (Mon 02 January 2023)
  5. DOM Clobbering (Mon 12 December 2022)
  6. Neue Methoden für Cross-Origin Isolation: Resource, Opener & Embedding Policies mit COOP, COEP, CORP und CORB (Thu 10 November 2022)
  7. Reference Sheet for Principals in Mozilla Code (Mon 03 August 2020)
  8. Hardening Firefox against Injection Attacks – The Technical Details (Tue 07 July 2020)
  9. Understanding Web Security Checks in Firefox (Part 1) (Wed 10 June 2020)
  10. Help Test Firefox's built-in HTML Sanitizer to protect against UXSS bugs (Fri 06 December 2019)
  11. Remote Code Execution in Firefox beyond memory corruptions (Sun 29 September 2019)
  12. XSS in The Digital #ClimateStrike Widget (Mon 23 September 2019)
  13. Chrome switching the XSSAuditor to filter mode re-enables old attack (Fri 10 May 2019)
  14. Challenge Write-up: Subresource Integrity in Service Workers (Sat 25 March 2017)
  15. Finding the SqueezeBox Radio Default SSH Password (Fri 02 September 2016)
  16. New CSP directive to make Subresource Integrity mandatory (`require-sri-for`) (Thu 02 June 2016)
  17. Firefox OS apps and beyond (Tue 12 April 2016)
  18. Teacher's Pinboard Write-up (Wed 02 December 2015)
  19. A CDN that can not XSS you: Using Subresource Integrity (Sun 19 July 2015)
  20. The Twitter Gazebo (Sat 18 July 2015)
  21. German Firefox 1.0 ad (OCR) (Sun 09 November 2014)
  22. My thoughts on Tor appliances (Tue 14 October 2014)
  23. Subresource Integrity (Sun 05 October 2014)
  24. Revoke App Permissions on Firefox OS (Sun 24 August 2014)
  25. (Self) XSS at Mozilla's internal Phonebook (Fri 23 May 2014)
  26. Tales of Python's Encoding (Mon 17 March 2014)
  27. On the X-Frame-Options Security Header (Thu 12 December 2013)
  28. html2dom (Tue 24 September 2013)
  29. Security Review: HTML sanitizer in Thunderbird (Mon 22 July 2013)
  30. Week 29 2013 (Sun 21 July 2013)
  31. The First Post (Tue 16 July 2013)