Opened 19 months ago

Last modified 18 months ago

#25737 new defect

Tor Browser's update check bypassed Tor once on macos, because of xpcproxy?

Reported by: cypherpunks Owned by: tbb-team
Priority: Medium Milestone:
Component: Applications/Tor Browser Version:
Severity: Normal Keywords: tbb-proxy-bypass
Cc: mcs, brade Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

I am on macOS, and my current setup involves an isolation proxy, custom pf rules, an application firewall and the tor browser bundle (7.5.3).

The firefox process has only localhost access to the tor.real process.
The tor.real process has only localhost access to the obf4proxy process.
The obfs4proxy process can only access the remote IP/port tuple.
I modified the tbb-torrc adding UseBridges 1.

During the latest (vidalia) startup, my application firewall warned me that a process named xpcproxy was attempting to directly connect to 82.195.75.101/443tcp.

Since a reverse dns lookup resolves to listera.torproject.org, I believe this to be non malicious, but I'd count the behaviour as a potential IP leak.

Firefox should wait for the tor process to be ready and spawn the call over a tor circuit; if not, a malicious ISP (eg) has the potential to enumerate users.

I denied the access and restarted the browser, but have not been able to reproduce yet. So this is possibly a race condition between firefox and vidalia, because of this I am unsure if this should be a tor browser or a tor launcher ticket.

How can I inspect this?

Child Tickets

Change History (21)

comment:1 Changed 19 months ago by cypherpunks

Why vidalia?

listera.torproject.org

https://db.torproject.org/machines.cgi?host=listera

extensions.torbutton.versioncheck_url

race condition

between torbutton and tor-launcher

comment:2 Changed 19 months ago by arma

Right, that connection looks like an update check. And it should be going over Tor.

Can you reproduce this issue with actual normal Tor Browser?

It sounds like you have some hacked-together thing that nobody else uses, and so that would be the first thing to look at if there are surprises.

comment:3 Changed 19 months ago by cypherpunks

Sorry for my wrong wording, I should have written tor-launcher, vidalia is an error.
And I am using the official bundle, not something hacked-together ...

The application firewall is a fork of https://github.com/objective-see/LuLu .

comment:4 Changed 19 months ago by arma

Summary: Tor Browser Bundle IP LeakTor Browser's update check bypassed Tor once on macos, because of xpcproxy?

Can you tell us which version of MacOS?

Do you have a system-wide proxy set?

comment:5 Changed 19 months ago by cypherpunks

10.13.4

No, I don't have a system wide proxy set: what I call an isolation proxy is a simple linux box, with filtering/redirection purposes. It's transparent.

comment:6 Changed 19 months ago by cypherpunks

Yet another reason for using Tails/Subgraph/Whonix.

comment:7 Changed 19 months ago by teor

xpcproxy is a macOS system service involved in RPC setup: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man8/xpcproxy.8.html

Does Firefox use it to set up multiprocess mode?
Even if it does, it seems really unusual for a RPC process to be making remote connections.
Do you know what the DNS query was for that IP address?

If you're using LittleSnitch as your application firewall, it sometimes logs connections against the wrong process. If the underlying bug is a kernel bug, then all application firewalls could be affected on macOS.

comment:8 Changed 19 months ago by cypherpunks

extensions.torbutton.versioncheck_url

and app.update.url

comment:9 Changed 19 months ago by gk

Cc: mcs brade added

What happens if you disable Tor Launcher from being started? Can you reproduce your issue then? You could start it once and disable it in the about:addons section. Or just set extensions.torlauncher.prompt_at_startup and extensions.torlauncher.start_tor to false?

That should not leak anything as the proxy preferences are hardcoded in the browser to avoid exactly the scenario you describe.

comment:10 Changed 19 months ago by cypherpunks

Sorry for my delay, I had to ask the network administrator: the logs and cache contain an entry for aus1.torproject.org.

A deactivation of the extension imply the warning "something is not working", surfing is impossible (connection refused). Same goes for manually tweaking the conf.

Would a stack trace be helpful (provided it's gonna happen again)?

comment:11 in reply to:  10 Changed 19 months ago by gk

Replying to cypherpunks:

Sorry for my delay, I had to ask the network administrator: the logs and cache contain an entry for aus1.torproject.org.

Logs and cache of what? The application firewall?

A deactivation of the extension imply the warning "something is not working", surfing is impossible (connection refused). Same goes for manually tweaking the conf.

Yes, that's intended. I was just wondering whether the supposed race condition could be avoided that way as Tor Launcher is now out of the picture and the update request should be visible every time it gets issued, in case Firefox is not obeying its proxy settings. You can see those requests in the browser console (Ctrl+Shift+J) after setting the logging pref extensions.torbutton.loglevel to 3).

Would a stack trace be helpful (provided it's gonna happen again)?

Could be. I guess ideally having some steps to reproduce your issue would be the best but as long as it seems to be semi-randomly happening (or happened once) that's hard.

I wonder if you see those calls with a normal Firefox as well? You could try with setting a proxy (Tor e.g.) and using that for a bit or just using the default Firefox, trying to reproduce those weird xpcproxy related firewall alerts.

comment:12 Changed 19 months ago by gk

Oh, another thing that might be interesting the next time is seeing the process hierarchy by clicking on the respective LuLu icon on the alert window.

comment:13 Changed 19 months ago by cypherpunks

    observe: function(subject, topic, data) {
      if(topic == "profile-after-change") {
        // Bug 1506 P1: We listen to these prefs as signals for startup,
        // but only for hackish reasons.
        this._prefs.setBoolPref("extensions.torbutton.startup", true);

        this.setProxySettings();
      }

comment:14 in reply to:  13 ; Changed 19 months ago by gk

Replying to cypherpunks:

    observe: function(subject, topic, data) {
      if(topic == "profile-after-change") {
        // Bug 1506 P1: We listen to these prefs as signals for startup,
        // but only for hackish reasons.
        this._prefs.setBoolPref("extensions.torbutton.startup", true);

        this.setProxySettings();
      }

What do you mean by pasting this code snippet?

comment:15 in reply to:  14 Changed 19 months ago by cypherpunks

Replying to gk:

Replying to cypherpunks:

    observe: function(subject, topic, data) {
      if(topic == "profile-after-change") {
        // Bug 1506 P1: We listen to these prefs as signals for startup,
        // but only for hackish reasons.
        this._prefs.setBoolPref("extensions.torbutton.startup", true);

        this.setProxySettings();
      }

What do you mean by pasting this code snippet?

Nothing.

comment:16 in reply to:  10 Changed 18 months ago by mcs

Replying to cypherpunks:

Sorry for my delay, I had to ask the network administrator: the logs and cache contain an entry for aus1.torproject.org.

To add to gk's questions: does the presence of aus1.torproject.org in your log mean that something did a DNS lookup on that name? I assume so, which means the leaked request was an application update request.

There are at least three possible explanations for the request you saw:

  1. At some point in the past, the default browser proxy preferences were modified. Then you started Tor Browser and an application update request was sent before the settings were reset to the correct values (which Torbutton does during application startup in conjunction with Tor Launcher). I think this scenario might occur if transproxy mode was enabled at some prior time.
  2. There is a bug in Torbutton or Tor Launcher which temporarily caused the wrong proxy settings to be configured. Looking at the code, I do not see such a bug but it might be there.
  3. There is a proxy bypass bug in Tor Browser (and probably Firefox as well) that is triggered under certain conditions.

comment:17 Changed 18 months ago by gk

Some discussion from today:

15:17 < Alex_Gaynor> tjr: Not sure I have a ton to contribute; we definitely use 
                     XPC IPC in process startup, but I can't imagine we're doing 
                     anything that intentionally causes a network connection. 
                     Dunno why an XPC process would need to make it's own network 
                     connections at all. I'm not sure I have anything to suggest 
                     besides using dtrace/lldb/something to capture the full 
                     stacktrace from XPCproxy when it makes the DNS lookup
15:18 <+tjr> Alex_Gaynor: Is there a particular function that does 'XPC IPC'? 
15:20 < Alex_Gaynor> tjr: 
https://searchfox.org/mozilla-central/source/ipc/glue/GeckoChildProcessHost.cpp#823-884
15:23 <+tjr> So everything that goes through a 'MachPortSender' or a 
             'mach_port_t' is ultimately going through xpcproxy?
15:25 <+tjr> And it seems like xpcproxy is technically capable of making network 
             connections given the right input (even if we don't know what that
             is) - so it seems like it could be used to bypass that sandbox 
             rule...
15:26 <+tjr> Assuming not "If you're using LittleSnitch as your application 
             firewall, it sometimes logs connections against the wrong process."
15:28 < Alex_Gaynor> tjr: I _think_, I can't say for certain I don't know a ton 
                     about xpcproxy

comment:18 Changed 18 months ago by tom

I talked with haik a bit also:

11:22:27 H<haik> In some cases I see it being called with "xpcproxy org.mozilla.firefox.14156"
11:22:53 H<haik> That 14156 is not a PID.
11:24:11 H<haik> Maybe turning on launchd logging can shed some light on what we're doing to trigger it. It's always started by launchd.
11:25:28 T<tjr> Hm. xpcproxy org.mozilla.firefox.14156    that first bit seems like a signing certificate or package identifier; but sure about the 14156 though. Maybe a port?
11:26:09 H<haik> Yeah maybe a port.
11:28:56 H<haik> So instructing the user to run "ps -ef|grep xpcproxy" might give us the arguments to xpcproxy at the time. Since it's basically a launcher, we want to know what it's launching that is doing the https requests.
11:29:33 H<haik> Or any way they can get the full command with arguments.
11:36:11 H<haik> OK, I think I have the logging setup locally so I should see what the arguments are if it happens.
12:05:27 H<haik> If you start the browser through Spotlight, it is started by xpcproxy
12:08:00 H<haik> And if you start it through Finder
12:10:28 H<haik> Hold on, not sure, "xpcproxy /Applications/.../firefox" is run, but not sure if that starts it

comment:19 Changed 18 months ago by tom

12:12:00 H<haik> OK, one last thing, my logging shows...
12:12:05 H<haik> EXEC:     launchd -> /usr/libexec/xpcproxy
12:12:05 H<haik>           TIME           STRTIME                 PID   PPID ARGS
12:12:05 H<haik> START:    1616533459     2018 Apr 10 10:09:54    963      1 xpcproxy org.mozilla.firefox.55196                                                                      
12:12:05 H<haik> EXEC:     xpcproxy -> /Applications/Firefox.app/Contents/MacOS/firefox
12:12:05 H<haik>           TIME           STRTIME                 PID   PPID ARGS
12:12:05 H<haik> START:    1616537512     2018 Apr 10 10:09:54    963      1 /Applications/Firefox.app/Contents/MacOS/firefox   
12:12:16 H<haik> When starting via Spotlight
12:12:46 H<haik> That EXEC line does mean that xpcproxy is starting Firefox

comment:20 Changed 18 months ago by gk

Keywords: tbb-proxy-bypass added

Tentatively putting that into our proxy bypass category even though it remains obscure on what is happening.

comment:21 Changed 18 months ago by cypherpunks

I'm the OP, someone else is using the cypherpunks account: such as in 1, 6, 8, 13 and 15. Just to clarify.

Yet another reason for using Tails/Subgraph/Whonix.

Unfortunately we need to work with Macs, using a separate workstation for browsing is too uncomfortable. We tried these days and it didn't worked out well. But Tor is part of our security posture, in the past we have been targeted and suffered a number of minor data breaches.

Logs and cache of what? The application firewall?

The logs and cache of the dns resolver. Which means the process did a DNS lookup on that name, around that time.

We are sure no outgoing connection has ever been made, because the firewall and the transparent proxy never logged any attempted bypass. I called it an isolating proxy because it inspects the traffic and blocks everything, except done for the connections to Apple, the bridge and our own IPs, redirecting each kind of traffic on a different route.

Oh, another thing that might be interesting the next time is seeing the process hierarchy by clicking on the respective LuLu icon on the alert window.

Did this: launchd -> /usr/libexec/xpcproxy. But I can not remember anything more specific than this now.

At some point in the past, the default browser proxy preferences were modified.

No preferences were modified: after the bundle installation, I inserted the bridge, closed the browser, opened ~/Library/Application Support/TorBrowser-Data/Tor/torrc and added UseBridges 1. Only usual browsing activity from thereon.

I'm not sure I have anything to suggest besides using dtrace/lldb/something to capture the full stacktrace from XPCproxy when it makes the DNS lookup.

So instructing the user to run "ps -ef|grep xpcproxy" might give us the arguments to xpcproxy at the time. Since it's basically a launcher, we want to know what it's launching that is doing the https requests.

Will do it if it happens again.

If you're using LittleSnitch as your application firewall, it sometimes logs connections against the wrong process.

Denying the outgoing connection blocked the progress of the launcher and the browser window never popped up. So, I find this unlikely. But maybe I'm missing something here?

Note: See TracTickets for help on using tickets.