Hacker News new | ask | show | jobs
Show HN: Firefox addon to quarantine a tab to use offline with private data
166 points by matusfaro 1005 days ago
Introducing QuaranTab: Companion extension to quarantine tabs so you can safely use them offline with private data

I find myself wanting to use online format parsers to quickly decode that production JWT or decode a base64 Authorization header but cannot trust these websites to not leak my information. I thought to myself if only I could cut-off network access to this site, use it offline, and then throw away all browsing data. So I created an extension just for that.

It uses Firefox contextual identities API (Containers) to isolate browsing data and inter-tab communication. Once the site is fully loaded, I then inject bogus proxy settings for any requests leaving that container to effectively cut-off network access. And once I'm done, I simply delete the Container.

Use Cases:

* Parse a live JWT token

* Convert a Base64 Authorization header

* Hash a password

* Parse a Protobuf message

* Submit my name and birthdate to estimate my date of death

Check out the MIT source code on GitHub [1] and install QuaranTab from the Firefox store [2]. If anyone is interested in a discussion, I'd love to chat about:

1. Any ideas on how we could implement this in Chromium? Using private window as a "Container"?

2. Can you come up with an exploit? I posted a 100usd bug bounty [3] if you find one!

3. Is there any way to prove an extension in the store was built from source in GitHub? I am imagining some kind of third-party escrow service managing the Firefox store account and building from specific public git repository.

1. https://github.com/matusfaro/quarantab

2. https://addons.mozilla.org/en-US/firefox/addon/quarantab/

3. https://github.com/matusfaro/quarantab#bug-bounty

15 comments

We have our first bug bounty!

Thank you "dz2742" for finding out [1] existing connections including websockets are not terminated and has won 100 USD! This is exactly the type of exploit I was hoping to catch.

Now I have to figure out how to fix that :) And also think about refilling the bug bounty pool without becoming very poor very soon.

https://github.com/matusfaro/quarantab/issues/2

Cool idea! I don't really picture myself using this, but I think this add-on is a great example of how great a browser Firefox is. I'd be the first to critique Mozilla, and there are definitely things about Firefox I don't like (ex. Pocket, telemetry on by default), but overall I think it's an amazing product in that it allows for multiple levels of isolation (profiles, containers, private mode) and a level of control over them that Chromium either doesn't do as cleanly or doesn't do at all. As an aside, the only thing I think Chromium does better is the debugging experience; I don't truly understand why Firefox thinks it shouldn't support debugging Node.js like Chromium does.
> it allows for multiple levels of isolation

Yes! Chrome has a visually similar functionality to Firefox Containers hidden away behind a feature flag [1] at the moment. BUT under the hood it's simply just tab grouping with no isolation. I presume isolation is against Google's interests so we will never see this kind of feature.

As for Firefox's API, the Contextual Identities API [2] that allows you to create/delete containers is amazing and easy to work with as a dev. And it works out-of-the-box, it doesn't need the companion addon Multi-Account Containers (MAC) [3] which really should've been part of Firefox in my opinion.

1. chrome://flags/#tab-groups-save

2. https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Web...

3. https://addons.mozilla.org/en-US/firefox/addon/multi-account...

Firefox's containers are useless for privacy, given other enhancements of Firefox (e.g., Total Cookie Protection). And as far as "isolation", privacy or security are concerned, Chrome's profiles are actually superior due to ability to have different extensions and history per profile. Chrome's extensions in general still have superior security (e.g., activate on click or only for certain websites), so sometimes different profiles aren't even needed.

Chrome's Profiles are also remembered when you "install an app" (SSB/PWA), so you could have "apps" started in their own profiles.

Firefox's containers are only useful if you want multiple logins to the same service in the same browser window. But I never found that usecase to be very compelling.

Firefox's containers are an often lauded feature, and I don't understand why, given the integration issues or general awkwardness. It's probably a reminiscence of the "Facebook container" extension, which was a bandaid until better site isolation was implemented.

A counter anecdote is that I have the exact opposite use case. I don't share my computer with other users, so I've never needed something like profiles. Firefox containers are great for keeping different sites, especially those notorious for tracking (e.g. Amazon, Google, LinkedIn) completely isolated from each other or from general browsing. Plus, the extension that allows for creating temporary containers is great for one-off visits to e-commerce sites without needing to switch to a new private/incognito window. I'm not sure I've ever wanted my extensions isolated by container/profile, that seems like it would hinder productivity. Same for history. It's great having all my history commingled, especially if I want to find something from 30 tabs ago.
> Firefox containers are great for keeping different sites, especially those notorious for tracking (e.g. Amazon, Google, LinkedIn) completely isolated from each other or from general browsing.

That was exactly my point; you're using Firefox's containers for privacy, and it actually doesn't help, at least since they deployed "Total Cookie Protection" by default:

https://blog.mozilla.org/en/products/firefox/firefox-rolls-o...

Note that other browsers have implemented similar strategies, notably Safari and Brave:

https://brave.com/privacy-updates/7-ephemeral-storage/

Also, blocking 3rd party cookies in Chrome is decent enough, as Chrome also does cache and network partitioning. The problem with blocking 3rd party cookies is that it breaks some websites, which is why something like "Total Cookie Protection" is a better strategy.

> That was exactly my point; you're using Firefox's containers for privacy, and it actually doesn't help, at least since they deployed "Total Cookie Protection" by default:

It does. Total cookie protection isolates per-site. What containers allow is for you to say, open a single review site in two different containers, and click on an Amazon link on that review site and not have the same Amazon cookies shared when you do so. It also allows you to very easily set per-site clearing settings for those 3rd-party cookies rather than relying on more cumbersome browser settings.

Total cookie isolation is a great feature but it's a very passive feature with very defined boundaries. Yes, your FB tracking cookies get isolated to the 3rd-party site requesting them. But when do those cookies get cleared, how do they get shared when browsing the same site? It's not just about saying "I want multiple Facbook logins at the same time", it's also about saying "I want this browsing session to be isolated even if I'm revisiting a site that has 1st-party cookies set, even if I'm loading 3rd-party cookies via a domain I've already visited."

By the logic you're supposing, private browsing windows themselves didn't have a purpose after total cookie protection was launched. But being able to fully segment site data by an arbitrary boundary beyond just domain boundaries is useful, and being able to set custom rules including (as this extension demonstrates) even custom proxy rules for how data within that boundary gets treated is even more useful.

Firefox has profiles too. Containers are for use within a profile. You keep saying that containers aren't useful but you don't elucidate on how they are useless for privacy or what integration issues exist. I don't know how to interpret 'general awkwardness.' Can you fill in some details?
On the usefulness of containers for privacy, I wrote another comment here: https://news.ycombinator.com/item?id=37477425

A problem I have with containers is one of usability, as they have integration issues. For example, when searching for open tabs (`%`), the container-enabled tabs don't get displayed.

Agree, though different profiles are a pain to use, I have to rely on the shell

   firefox -P profile2
You can use about:profiles to open profiles in new windows by simply clicking a button.
> Chrome's profiles are actually superior due to ability to have different extensions and history per profile

Interesting attack vector I haven't thought about which could leak information out of a network-locked Firefox Container. It would be under an assumption you have either:

1. A malicious extension installed (you have a much worse problem in this case)

2. A side-effect of an existing extension that leaks information to the outside world. (e.g. translate a part of a page, lookup a word in a dictionary, pre-fetch some images...)

> Firefox's containers are only useful if you want multiple logins

I think there are valid use cases for both Containers and Profiles. You can go down the list to have more and more isolation as needed:

- Grouping tabs to stay organized, no isolation

- Firefox containers, same browser window, shared history & extensions

- Chrome profiles, almost complete isolation within same browser (different processes)

- Separate browser instances

- Separate devices

On extensions, for example, I use LanguageTool [1], which is similar to Grammarly. It could be configured with a local server, although I have a “premium” account which sends data to a 3rd party server. I trust this extension to verify my messages on HN, but I can't trust it to have access to my banking account. This is an example of a really useful extension that I'll never be able to fully trust because it has access to all websites, and it sends all that I write to another server.

In fairness, Firefox's advantage has been that Mozilla has a trustworthy manual review process for the “recommended” extensions.

[1] https://languagetool.org/

Note that languagetool doesn't need to request <all_urls> as a required permission, it could request hosts in optional_permissions (https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Web...) or (likely better) it could use activeTab permissions since it really shouldn't have access to your HN page until you invoke it anyway. The MDN docs even bring this up as an example scenario:

> The extension may need host permissions, but not know at install time which host permissions it needs. For example, the list of hosts may be a user setting. In this scenario, asking for a more specific range of hosts at runtime, can be an alternative to asking for "<all_urls>" at install time.

What we're waiting on I think is for Mozilla to get rid of the ability for extensions to opt out of this system, because I think one thing we've learned from extension permissions is that most devs are lazy and will just request the broadest permissions allowed if they have the option to do so.

One thing I'd really like to see extended is for "trusted extensions" that have gone through manual review to have a harsher standard applied to them by reviewers about what permissions they really need to request. I would love to see Mozilla pushing back a little on extensions like Languagetool and having reviewers ask "why aren't these permissions optional?" I feel like it's a little bit irresponsible for Mozilla to put its signal of approval on extensions that are over-requesting access beyond what's necessary even if those extensions aren't currently abusing that access.

Firefox containers aren't meant to be a substitute for profiles, they're a middle layer of security between profiles and private windows. This is exactly what GP was talking about with "layers" of isolation.

Firefox also supports profiles; they have the same isolation as Chrome profiles with the added benefit that they can be stored anywhere on your harddrive, meaning that you can even encrypt a Firefox profile on an external drive and have your history/settings only loaded when that drive is mounted and unencrypted. I will agree that the UI could be a bit better (switching between profiles is cumbersome), but it's a somewhat minor complaint in the same vein as my complaint that containers require an extension to be user-accessible.

Firefox containers are for when you do want to share history/settings, particularly privacy extensions and browser settings, but you want to isolate data between tabs in a way that goes beyond total cookie protection (funnily enough also a feature that Chrome doesn't support) -- containers allow you to isolate cookies between multiple "instances" of the same site, set rules for when site information should be cleared, and they allow extensions to hook into that API in a way that cookie containers don't (to the best of my knowledge) support.

I'm not saying that I wouldn't like having the option to isolate more data with containers (extension settings would be welcome), but that's not really an issue with containers as much as it's just that I'd like Firefox to go even further with offering more granularity. It's annoying to make a profile and need to synchronize settings and extensions from my previous profiles.

> Chrome's extensions in general still have superior security (e.g., activate on click or only for certain websites), so sometimes different profiles aren't even needed.

I also want to throw out a quick objection here: Firefox supports Manifest V3 (extended to include adblocking power-features that Chrome has been removing) including website-specific permissions, optional permissions, and click-to-activate. It does not (as of now) require using Manifest V3, but I think their recent announcement about mobile extensions does require V3, so the writing is on the wall.

The lack of requirements is an issue, but if you're trying to build a sandboxed/secure extension, I'm not aware of any extension security APIs or settings that Chrome has that Firefox doesn't support. Site-specific activation I think works the exact same way. Short-lived background scripts are in there. I'd be curious to hear if there's anything missing. And of course Firefox allows users to disable auto-updating extensions as well.

Firefox's profiles are next to unusable for me.

They are a hidden feature, and switching isn't easy (I know of about:profiles). On macOS, they also have window management issues, as the operating system regards different profiles as being entirely different apps, so quickly switching between windows doesn't work (and setting specific app icons isn't easy).

On extensions, everything that has to do with Firefox's profiles requires separate programs to be installed on the user's computer. For example, PWA SSB support, which is cool, but barely works: https://addons.mozilla.org/en-US/firefox/addon/pwas-for-fire...

---

On site-specific activation of extensions, I sure hope to see the option in Firefox. For the extensions that I have installed, it doesn't seem to work yet, but you're probably right that they'll implement it eventually.

> On macOS, they also have window management issues, as the operating system regards different profiles as being entirely different apps, so quickly switching between windows doesn't work (and setting specific app icons isn't easy).

I understand the complaint but this is also sort of intended, right? Profiles are completely separate, they are effectively separate programs. They shouldn't be treated as shared context, they are effectively separate installations of the same program they can even be stored in different places on disk. So this seems like correct behavior?

Like, I get what you're saying, but it doesn't sound like your complaint is that profiles aren't encapsulated enough, it sounds like you want something less encapsulated and isolated than Firefox profiles. Of course you can't have an extension that manages your profiles without a separate application, extensions are completely isolated between profiles. Of course you can't share extension information between them, if Chrome allows that that's a weakness of their implementation.

I totally agree that the UX for profiles should be surfaced more (and I think that would be easy for Mozilla to do, a dropdown menu like Chrome offers would be enough). Containers themselves are hidden features in Firefox and I think that's a problem. I agree that profiles should be manageable without going to about:profiles. I'd be open for more isolation tools that sit between containers and profiles too.

But to argue that Chrome is offering more security here when from the sound of things Chrome has less profile isolation than Firefox sort of feels backwards to me. I doesn't sound like you want full isolation, what you want is a less secure version of Firefox profiles that sits between containers and profiles. That's fine, I think that's a completely reasonable ask -- but we should acknowledge that this is not the same as Firefox not offering isolation tools. Firefox does offer isolation tools, they work just as well if not (from the sound of your description) better than Chrome's tools do at actually fully isolating from each other. But it turns out that many users want profile-like tools that trade off some of that isolation and security in favor of greater usability.

The usability is an extremely reasonable complaint. But it just annoys me a little bit to hear someone saying that Chrome has more secure isolation for profiles if their complaints boil down to "Firefox isolates too well, and my OS doesn't ignore that isolation, and extension helpers don't ignore that isolation."

Umm, yes, yes it does - they're also called profiles and work the same way.
Firefox really needs to release containers for mobile.
The Contextual Identity API indicates that it's supported [1] in Firefox for Android so will need see how usable it is. I was planning on testing my extension on Android soon.

Looking into it more, there is an open request to complete the work in Android Firefox [2] and also to make the MAC extension for Android too [3]

1. https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Web...

2. https://bugzilla.mozilla.org/show_bug.cgi?id=1807456

3. https://connect.mozilla.org/t5/ideas/multi-account-container...

Many of the use cases mentioned are available through a single tool called CyberChef.

There is an online version [1] but it doesn't submit any data to any servers. It only loads JS for the operations it needs to perform.

You can also download it and run it offline [2]. This is what I do.

I'll leave it up to you to decide if this makes QuaranTab unnecessary or if it's the perfect reason to use QuaranTab.

[1] https://gchq.github.io/CyberChef/

[2] https://github.com/gchq/CyberChef/releases/

This extension is still very cool.

+1 to Cyberchef, its awesome. If you really have qualms about the URL its trivial to re-host / serve it to yourself offline.

My favorite part is whole recipe feature (Cyberchef builds a URL with the configured processors you use to process data).

I find myself using that a ton to share XPath / JPAth expressions type work with sample data to others by sharing that URL.

I've been curious about this: Is there a way to exfiltrate data from a locally downloaded single page application?

Due to the same-origin principle, plain XHR and similar should be out, but what about CORS or script/image embedding with query parameters?

Data exfiltration works just fine with a locally downloaded SPA. There's Script/image embedding as you mention. There's also iframes and form submissions.

As for XHR, the same-origin principle doesn't prevent the request from going out; it prevents the response from being readable by the page. Even so, a remote site can add the right CORS headers to allow access from anywhere, and your browser will happily send the data out AND allow the page to read the response.

You could probably mitigate most, if not all, exfiltration using a CSP [1] that you manually add to the HTML meta tag.

The reason for using a local copy is so once I verify that the copy I have is "clean" (either built myself or reviewed, and confirmed to not send data out) then I can trust that version until I replace it.

If I load data from a website, there are no guarantees that I don't get a different version every time.

[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

It's possible if the destination allows it, like Google Analytics
I know this won't land well, and certainly it's a good option, but there's a terrific and hilarious irony in someone saying "I don't really trust the third parties with my non public data" And you're like, yeah use the one tool that's built and maintained by a literal spy agency.
Yeah, that one has been argued to death in other places. And people bring that up about Ghidra, the reverse engineering tool developed by the NSA. I look at these tools suspiciously too.

Even so, the irony is only shallow. I haven't yet found a suitable reason not to use such tools if they're not sending out data, regardless of where the tools come from. The FAANG companies are far better at collecting your data, and do so brazenly.

Interesting project! Off the top of my head I guess it would be a larger addition since this is currently using built-in Firefox features for isolation, but recording/caching requests that are made during the initial load in order to "freeze" a website until the user chooses to update would make this more useful.

If you do want to go down that route, using the blocking `webRequest` to record responses and stick them into storage and then re-serve them from the cache would possibly be the best way to go about it. At that point though I'd probably advise seeing if you could get off of `<all_urls>` as a required permission? And I haven't ever played with blocking network requests for websockets, so I'm not sure if they'd require separate handling.

Just a thought. But regardless, thanks for sharing :)

> 3. Is there any way to prove an extension in the store was built from source in GitHub? I am imagining some kind of third-party escrow service managing the Firefox store account and building from specific public git repository.

This is (in theory) part of Mozilla's review process, and depending on how the extension is submitted they can (I've heard) be fairly strict about it. But it's not user-facing at all and I don't know how universally they review source code.

It really needs to be fixed from Mozilla's end though; I don't see much reason to get a 3rd-party involved instead of to lobby Mozilla to add some kind of process on its own that's more prominent. A 3rd-party verification service would be possible (you'd just download the extension from Mozilla's servers and extract it, re-run the build process and check to see if the artifacts matched), and in theory you could even have a completely separate extension store from Mozilla's -- as long as the extensions are signed you can host them anywhere, and there's nothing preventing you from getting other extensions built from source signed. You could have a pseudo-F-Droid addon store that distributed Mozilla-signed extensions you've pulled from Git and built yourself.

But... I mean, I just feel like it's something we should lobby Mozilla to do, they're in the best position to do it and in the best position to have the most impact if they do.

While I applaud your effort and thinking of privacy issues, I will continue to do these in a terminal and Python REPL for all the reasons you bring up.

It would certainly be nice to get something ala F-droid for free software extensions like yours (which guarantees source code matches built package IIRC), as a response to your question 3.

I am sure one can create an alternative extensions store in FF and change some config in about:config to use it, though it's likely non-trivial.

Agreed, and to be honest, this extension is more for myself as I would be extremely skeptical if someone else made it especially with the permissions it requires.

It would probably be more successful as a feature added to an existing trusted extension such as Temporary Containers.

> I will continue to do these in a terminal and Python REPL for all the reasons you bring up.

Do you have a way to prevent terminal utilities from accessing the network?

  $ bwrap --unshare-net --dev-bind / / bash
  $ curl google.com
  curl: (6) Could not resolve host: google.com
Or you could use firejail, or do it manually with `unshare`, or with any of the container runtimes (docker, podman).

https://wiki.archlinux.org/title/Bubblewrap

https://wiki.archlinux.org/title/Firejail

Interesting options, wasn't aware of those.

The only minor counter-argument would be laziness as a security threat: the more difficult you make the process, the more likely the user will skip seemingly useless steps, thus compromising security.

I generally avoid non-trusted utilities altogether. I am most likely to load up data (for the use cases mentioned in the extension description) into a Python shell and deal with it using json, base64, pprint and similar modules.

Some things I can do with regular POSIX and GNU tools directly from the CLI, so I'd trust those too on my Debian/Ubuntu systems (where there is usually a guarantee you can get the source code for the binary you are running). It's definitely possible Debian/Ubuntu experience a supply chain attack too, but it's significantly less likely than a random library from github IMO.

> Submit my name and birthdate to estimate my date of death

Totally off topic, but curious how this works? Nationality and life expectancy? Sex at birth? Assassins for hire?

DNaaS: Death Note as a Service
What actually triggered my idea was a recent DNaaS HN post [1] that tells you your expected life expectancy and other cool facts based on your country and birthdate which I was reluctant to input my actual birthday.

1. https://news.ycombinator.com/item?id=37324733&

Oh my god, this is scary. I don't want to live until the 2060s, lol. It terrifies me to think about how the world will be then...

But anyway, thanks for the link!

For the curious, this is their methodology:

> Remaining life expectancy at specific age (in days) was obtained by interpolating (spline) the 5 yearly/duration age-specific period life expectancies.

> Population.io uses official demographic data produced by the United Nations and published in the World Population Prospects

Actuarials publish tables based on all of that data, and more
Cool add on! Thanks for this. It's a use case I've often thought about, for the purposes you mention. I wish there was a built in permission to disable AJAX after page load. Bad for ads, I guess.

2. Exploit idea (not trying for the bounty, just thinking aloud). I wonder if a website could play background music (or a video) with stenographically encoded data, then another tab could listen to it with microphone permissions on and decode it that way. I'm thinking like a fake video conferencing site, or malicious telephony how-to doc that deals with API calls and such and links to a fake password hasher that then plays the audio for the first tab to hear. Convoluted, I know, just an idea.

> built in permission to disable AJAX after page load

Interesting, but consider this is a cat-and-mouse game. If you are the only one using this trick it may work for you, but I assume would be easy to overcome. (e.g. keep the page loading forever or until ads are loaded. Have the ads be J-free after page load, ...)

> website could play background music ... another tab could listen

You would need mic access from the other tab, but yes. If you send it over high enough frequency you wouldn't even hear it. You would just have a visual feedback that the tab is playing music.

On a side-note, I recall there was some kind of hardware device pairing (maybe Chromecast?) that used data over voice to establish that you are physically near the other device.

> On a side-note, I recall there was some kind of hardware device pairing (maybe Chromecast?) that used data over voice to establish that you are physically near the other device.

Yeah, that's pretty common in home smart devices. Looks like Google patented one version and Sonos has their implementation too. In my experience it works better than Bluetooth, especially in (2.4 GHz) noisy environments

Funny that you say Sonos.

I also remember there was a data-over-voice library called "chirp.io" which now redirects to Sonos homepage. Now I know why they acquired them :)

I wonder if it's also part of the patent battle they got in with Google over smart speaker stuff.

Side rant: It's so sad, to this day Google Assistant works terribly on my Sonos system, and it's a major reason I'm reluctant to further buy into their ecosystem. And Sonos's own assistant doesn't even support Spotify, last I checked. Their whole UX is... not great. I really wanted to work there and maybe try to fix some of the issues I experience as a user, but they rejected me. Alas.

A (user-unfriendly-but-workable) solution for chromium is Devtools->Network->Network Conditions->Offline, then clear all storage and cache after you're done.

This only works if you have one tab of this website, since tabs of the same website can message each other (and exfiltrate data).

Also useful for debugging frontend bugs in "destructive" operations in production :)

I wonder how far you could get in accomplishing the same thing by setting a Content Security Policy (CSP) [1] on the page.

[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

You can add to your uses cases a web viewer for MRI/CT scan results https://madacol.github.io/ozempic-dicom-viewer/
that's a nice idea

the same way you can silence the sound output of a tab you should have as simple and reliable a tool to stop communication to either the network, os or both.

i'd love a tool to see which tabs are talking with each other also

> love a tool to see which tabs are talking with each other also

Cool idea but probably not that useful and difficult to accomplish. There are many ways to communicate that could be grouped into:

1. tab -> tab (same domain)

2. tab -> tab (different domain)

3. tab -> server -> tab

For #1, there are so many ways to transfer information it would be hard to detect and differentiate whether it's communication or just happens to be using the same resource. (e.g. one sets a cookie or local storage and the other one reads it)

For #3, it would be impossible to detect. Especially if detection is an issue, both tabs could be communicating with unrelated servers which talk with each other.

For #2, it would be the only interesting one as there is limited options (e.g. Broadcast Channel), but at the same time I assume rarely used in practice. And if detection is an issue, they would switch to #3 to avoid it.

It would be nice if the code in the .xpi wasn't minified.
I can certainly do that. I used a browser extension boiler plate that minifies it by default. I submitted an issue for myself to fix this [1]

1. https://github.com/matusfaro/quarantab/issues/3

Thanks, now I can begin using https://gpx.studio