How to access local HTTP service from Tor Browser?

Hi,

I am using Whonix 17 on Qubes OS 4.2.

I am looking for a way to access a super simple local HTTP server (python3 -m http.server <port>) from Tor Browser (in Whonix-Workstation-based AppVMs) and from Firefox (in Debian clearnet AppVMs). The HTTP service must be accessible only from such local AppVMs and DispVMs (no exposure to the LAN or WAN).

I am aware of this approach and it works fine, but I am concerned that it may have undesired and unsuspected side effects on privacy, so I hope for something safer.

It seems a good idea to host the HTTP service on a dedicated AppVM, but I don’t have the slightest idea which NetVM to use (sys-whonix, sys-firewall or any other) and how to set up restrictions correctly, considering the requirements.

What is the correct and secure way to do this?

Does not exist.

none. Literally none.

Could you elaborate?

non-networked

I know what netvm=none means.

By elaborate, I mean:

Why a safer way does not exist?

Or do you mean that what I linked to is the safest?

How do you envision the whole thing (without a NetVM)? Or if you don’t - why are you rejecting the possibility of it?

You can access local services by disabling network.proxy.allow_hijacking_localhost in about:config. Doing it inter-VM is probably not a good idea.

Network over qrexec but that could be hard because Qubes documentation isn’t the best.

Because there’s no serious alternative to Tor Browser. Doesn’t exist. Therefore there is no safer way than what’s in the wiki.

You can access local services by disabling network.proxy.allow_hijacking_localhost in about:config.

How safe is that considering the link in the OP?

Network over qrexec but that could be hard because Qubes documentation isn’t the best.

I have never done this. Are there at least any examples of such setup (HTTP over qrexec)?

Because there’s no serious alternative to Tor Browser. Doesn’t exist. Therefore there is no safer way than what’s in the wiki.

Ah. There is some misunderstanding. I am asking for a safe way to do what I am trying to do, not for an alternative to Tor Browser.

Not a Whonix issue. It’s a Qubes issue.

It’s already the safest solution you already found in the wiki. Safer would only be not using. To be safer either Tor Browser would need to be improved (good luck) or a browser safer than Tor Browser would be needed. Since both doesn’t exist, this being a very minor and very niche issue, you reached a dead end.

To avoid opening direct connections to 127.0.0.1 (which, IIUC, is unsafe), I tried to add a second loopback IP address:

sudo ip a add 127.0.0.2 dev lo
sudo route add -host 127.0.0.2 dev lo

From the command line, I can curl to the locally running HTTP service on any of the IP addresses (127.0.0.1, 127.0.0.2). Not in Tor Browser though. Same VM.

Is there a way to make this work?

I would not know why .1 would be more/less safe than .2.


That’s a Tor Browser configuration question.
Whonix doesn’t influence that and doesn’t develop Tor Browser.
This issue is unspecific to Whonix.

You could attempt to resolve it as per:

I.e. redirect the question to Tor Browser.

Are the Recommendations insufficient?

The conclusion from Local Connections Exception Threat Analysis being: don’t browser any other websites from that browser in that VM.

The real solution would be to pay someone (not me) to fix the root issue:

I would not know why .1 would be more/less safe than .2.

Because .1 goes to sys-whonix as a socks proxy?

Are the Recommendations insufficient?

I don’t even see how they are related.

The conclusion from Local Connections Exception Threat Analysis being: don’t browser any other websites from that browser in that VM.

Also unrelated. It talks about JavaScript. I need the HTTP service to serve only trusted static content which is non-sensitive - public text files which exist on the web, just cached locally.

The XY problem I am solving is: I am customizing Tor Browser through policy.json. The customization includes uBlock Origin (yes, I know - not recommended but for my particular threat model I am confident it improves things). The policy.json file is in a DVM template without networking. uBO is also there as an xpi file where necessary and the policy.json controls its settings too. No other file modifications are applied. The only thing that’s left is the filter list updates. Since it takes a significant amount of traffic and would create a pattern to download them on each start, I created a shell script to download them locally. The problem is that Firefox extensions cannot access local file:// URI scheme, so uBO needs HTTP to create/update it’s idb.

So, after spending a week fighting all this, this is just the last step. It would provide a way to have disposable Tor Browser with uBO without persistent profile and disabled filter updates. Filter updates will happen in another VM, at different time, so there won’t be two VMs using Tor at the same time.

Once this last piece is completed, I will be able to share the setup for anyone who decides to use it (I have seen people asking about similar things) for a similar threat model.

1 Like

That is certainly interesting.

To locally test a website running on my local VM using a local browser, I modified /etc/hosts file, installed a local TLS certificate and then could locally access the domain name whonix.org even no remote server has been contacted. That was hard. That works with Firefox and Chromium. But this won’t (easily) work with Tor Browser as it ignores /etc/hosts file for good reasons. (Also DNS over HTTPS (DOH) would circumvent that.) So I am not sure that’s an inspirational pointer.

These are Firefox, Tor Browser issues. The root issue is with Firefox. Tor Browser inherits these. By extension, Whonix inherits these.

Did you consider to place the filters file directly inside the Firefox profile? Dunno if that is possible.

Good point. Did you verify there is no such issue on .2?

I gave the wrong link. What I meant, now fixed links:

These recommendations are a sub chapter of the local connections chapter. But yeah. A bit confusing chapter names.
(two chapters called “Recommendations” and not the best name for the chapter)

This chapter is linked from Local Connections, quote:

The configured exception means a small trade-off in privacy, but it is much safer than using another browser (see Local Connections Exception Threat Analysis).

In context of local connections, quote:

Disabled JavaScript mitigates these browser fingerprinting issues completely.

So if you can disable JS + allow local connections in Tor Browser according to latest understanding there is no issue.

This could be very difficult…

Programatically,

  1. Start HTTP server.
  2. Start Tor Browser.
  3. Disable JS (if possible).
  4. Update filter lists.
  5. Terminate Tor Browser.
  6. Stop HTTP server.
  7. Do normal browsing.
1 Like

Did you consider to place the filters file directly inside the Firefox profile? Dunno if that is possible.

It is possible but it doesn’t solve the issue - it is not possible to use file:// URI scheme as an URL from which to refresh the filter lists. It must be http://.

Good point. Did you verify there is no such issue on .2?

The socks proxy is only on .1, right? What issue is expected to exist on .2?

I linked to that in the OP (just using the .onion domain), i.e. I am aware of it and it works, but it is recommended against.

In the setup I am building:

  • The handcrafted policy.json enforces Safest mode by default
  • JS is disabled through user.js
  • JS is disabled through uBO
  • all 3rd party stuff (including 3rd party scripts) are disabled in uBO

The user is still free to re-enable each of those but one must do it explicitly and consciously, going through multiple steps (deliberately difficult). Even so, the setup allows granular control through uBO (e.g. to/not run 3rd party JS, fonts etc), additionally blocking known bad stuff (what the filter lists are for).

The configured exception means a small trade-off in privacy, but it is much safer than using another browser (see Local Connections Exception Threat Analysis).

Oh, that. Of course, I have read it too before opening the thread. As clarified in the OP, I am looking for a safe solution which would not introduce additional threat. I don’t mean another browser. I mean a safe solution within Tor Browser.

I don’t know how JS can “scan internal networks, fingerprint devices, and make malicious commands to those devices if they have a web interface”, as described in the linked bug report, on a Whonix-Qubes system. The Whonix gateway connects to sys-firewall and that’s all, right? What internal networks and devices are we actually considering?

In context of local connections, quote:

Disabled JavaScript mitigates these browser fingerprinting issues completely.

So if you can disable JS + allow local connections in Tor Browser according to latest understanding there is no issue.

As clarified above, JS will be off by default. However, the user should still be able to explicitly enable it selectively, which is a case that supposedly no longer belongs in the completely non-issue category, yet we should consider the actual environment: Whonix + Qubes.

I am thinking how exactly a malicious JS can exploit the described XY and what it can do.

  1. It will need to bypass uBO’s protection (blocking all 3rd party requests by default)

  2. It will need to bypass sys-whonix and sys-firewall to scan local network.

IMO, we can simply wish “good luck” to such script.

Perhaps it makes sense to consider a scenario of a website JS considering the actual system - Tor Browser in a diposable.

It may need a combination of browser bugs allowing the malicious script to bypass the protection of uBO, e.g. through a buggy browser API in combination with buggy built-in browser security. If that is possible, what exactly can such JS do? Read the filter files/names, then leak info about them to entity X, thus fingerprinting the user?

If that is the supposed anti-privacy attack, it must consider and target factors like:

  • the exact browser and extension setup
  • the exact time frame of the potential combination of bugs
  • the fact that this is all running in a disposable where the filter lists may be different in a day (or even after an hour), i.e. non-persistent data

That seems to rather fall in the category theoretical and very unlikely, kind of AI-over-JS level. What do you think?

Why a connection to an URL is required? I mean, what would that process to by default without modifications? The end result is most likely that some file somewhere in the filesystem gets updated, right? I am suggesting to simply change the file behind the add-on’s back. The add-on shouldn’t notice and “think” it was previously updated from a URL.

There could be complicates (these files could be in binary format or something else ugly) and you might need to understand the add-on’s source code and/or ask its authors how to do that and/or request a feature to allow manual file-based updates.

Not possible without fixing this issue at the root, that is fixing the bug reported to Mozilla.

Presumably a JS feature. Follow Mozilla’s or Tor Project’s bug reports to learn more if needed.

Unspecific.

  1. The root issue: Firefox
  2. Inherited by: Tor Browser
  3. Inherited by: Whonix

The issue is - according to the bug reports - reproducible with Firefox and Tor Browser if allow local connections.

Whonix doesn’t change anything about it, because that’s difficult and the only way to fix it is at the root, inside Firefox.

Examples:

  • In case of Firefox on Debian: by default afaik until Mozilla fixes the bug - if cups was listening on 127.0.0.1 then JS might be able to detect that this port is open.
  • In case of Tor Browser on Debian: after enabling local connections - JS might be able to detect a Tor SocksPort on 127.0.0.1 9150 and ControlPort on 9151
  • In case of Tor Browser on Whonix: after enabling local connections - same as above.

In case of Whonix: at most SocksPorts / ControlPort on Whonix-Gateway. Local network: no.

I am not aware if uBO or any add-on can block JS based fingerprinting of open localhost ports.

Right but we not only care about the local network but also hiding fingerprinting of localhost listening ports.

After watching iPhone backdoor video at CCC by Kaspersky researchers…

Video YouTube icon Invidious icon Onion icon 37C3 - Operation Triangulation: What You Get When Attack iPhones of Researchers

…it seems insane through what lengths some attackers go. So I will keep staying away from making “non-issue” statements.

Why a connection to an URL is required? I mean, what would that process to by default without modifications? The end result is most likely that some file somewhere in the filesystem gets updated, right? I am suggesting to simply change the file behind the add-on’s back. The add-on shouldn’t notice and “think” it was previously updated from a URL.

https://discourse.mozilla.org/t/how-to-access-local-files-from-an-extension/92190/7

The above info is quite confusing because according to this it should be possible but perhaps this explains it:

“Keep in mind that just because Firefox allows your extension to execute JS within file: URL (with the ‘<all_urls>’ or ‘file://*’ permission) does not mean you can open a file: URL programmatically.”

Also:

Re. the “end result” you talk about - uBO stores everything in a local database and that is not one file.

https://discourse.mozilla.org/t/can-an-extension-install-with-a-pre-loaded-indexeddb-database/41988

In short - I have considered even the possibility to update the DB directly but I gave up quickly as it looks an extremely complex path.

  • 127.0.0.2: does not but should be verified.

How?

FWIW, I have also tried other IP addresses, e.g. 127.0.1.1 (same result as .2). I even tried 1.1.1.1 + a firewall rule which forwards it to 127.0.0.1 - that also doesn’t work as expected. Tor Browser goes to Cloudflare’s website and my tricks don’t work. Tor Browser simply proxies everything through sys-whonix. curl obviously does not.

Not possible without fixing this issue at the root, that is fixing the bug reported to Mozilla.

If a bug has not been fixed for 18 years, I don’t expect it to ever be fixed.

Unspecific.

I think it is specific because the bug you linked to implies the possibility to scan every device reachable over the LAN. I am asking - how will that happen in Qubes? Is there any JS PoC that scans and detects the other running network-connected VMs through Tor Browser or Firefox. I couldn’t find any.

  • In case of Firefox on Debian: by default afaik until Mozilla fixes the bug - if cups was listening on 127.0.0.1 then JS might be able to detect that this port is open.

OK. Suppose that is possible. How does that affect us?

  • In case of Tor Browser on Debian: after enabling local connections - JS might be able to detect a Tor SocksPort on 127.0.0.1 9150 and ControlPort on 9151

So, the website will know “This is Tor Browser” which it knows anyway (through the IP address and specific version in user-agent header).

In case of Whonix: at most SocksPorts / ControlPort on Whonix-Gateway.

Same ports from above? What is the result of that?

Local network: no.

That’s what I mean when I say Whonix-Qubes’s specifics matter.

I am not aware if uBO or any add-on can block JS based fingerprinting of open localhost ports.

Can you show a PoC website where I can test this? I couldn’t find a single reliable one. uBO blocks successfully any 3d party requests (with or without local access enabled). Local IP addresses are 3rd party in regards to anyexample.com. Or what do you mean?

So it’s a complicated file format so that you cannot update that at the ~/.firefox folder file system level? That seems really bad but not surprising because the big browsers have an awful technical design with everything and the kitchen sink.

By default it talks to local SocksPort 9150 inside Whonix-Workstation.
(systemd-socket-proxyd listening port redirection)

Then that is unfortunately the end of it.

It doesn’t. JS can only do what the environment where it is running allows. And if the browser allows JS to scan local listening ports then that’s that. But local LAN cannot be scanned because in Qubes the VM is connected to sys-firewall (or sys-whonix), so nothing to gain there. That’s hard restriction imposed on the VM imposed from the virtualizer.

I am not aware of any PoC.

It does not as long as you follow recommendations and do not enable local connections in Tor Browser. But if you do, you’re fully affected according to Mozilla upstream bug report except that the VM imposes damage control. (No access to local LAN.)

If you read https://bugzilla.mozilla.org/show_bug.cgi?id=354493 it is worse:

According to the linked article, JavaScript can be abused to scan internal networks, fingerprint devices, and make malicious commands to those devices if they have a web interface.

It can communicate with localhost as much as you can do locally which is pretty bad.

Not sure it is like that. If you want to know for sure, read that upstream bug. I could not easily find the article that was mentioned.

curl is preconfigured to use uwt. So it talks to a Tor SocksPort by default, except with circumvented.
References what uwt is here: Stream Isolation

netstat -tulpen

No, I am only trusting that Mozilla would have closed that bug as invalid if this was a non-issue or that the Tor Project wouldn’t have disabled localhost connections as a result of it. I am not a browser core developer. This is a “different department”.

So it’s a complicated file format so that you cannot update that at the ~/.firefox folder file system level?

Right. It must be done through the browser API. There is even the additional complication that uBO actually atomizes then deduplicates all filters, so it is not even simply loading of data in to a DB.

What about the idea to run the HTTP server in a separate VM, restricting it to local connections only? Is there a way for sys-whonix to connect to such server without torifying that particular connection (only)? If that is possible, then nothing in the browser would need to be touched.