Opened 4 years ago

Closed 4 years ago

Last modified 3 years ago

#10419 closed defect (fixed)

Can requests to 127.0.0.1 be used to fingerprint the browser?

Reported by: mikeperry Owned by: mikeperry
Priority: Very High Milestone:
Component: Firefox Patch Issues Version:
Severity: Keywords: tbb-fingerprinting, tbb-pref, MikePerry201401R
Cc: gk, oc Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

If a site makes connection attempts or element loads sourced for 127.0.0.1, can it build a list of open local TCP ports for fingerprinting purposes? Open ports may yield different error conditions than closed ports for certain request types and elements..

There may be other vectors to to this through DNS rebinding too, but I believe in those cases the hostname should always be provided to the SOCKS port, and such connections will happen to the exit, which should block them.

Child Tickets

Change History (40)

comment:1 Changed 4 years ago by gk

Cc: gk added

comment:2 Changed 4 years ago by cypherpunks

(cypherpunks2 from from #10686 here)

Copied from the old ticket: Why not set

user_pref("extensions.torbutton.no_proxies_on", "");
user_pref("extensions.torbutton.saved.no_proxies_on", "");
user_pref("network.proxy.no_proxies_on", "");

and just let tor reject the connections?

I've grepped the 24.2.0 source tree for "127.0.0.1" and could find nothing to suggest that Firefox uses the address internally: The only occurrences of the string were inside of unit tests.

comment:3 Changed 4 years ago by cypherpunks

I've grepped the 24.2.0 source tree for "127.0.0.1" and could find nothing to suggest that Firefox uses the address internally: The only occurrences of the string were inside of unit tests.

What about used extensions?

comment:4 in reply to:  3 Changed 4 years ago by cypherpunks

(cypherpunks2 here)

Replying to cypherpunks:

I've grepped the 24.2.0 source tree for "127.0.0.1" [...]

What about used extensions?


Good point, but there are no interesting matches in those either.

And Torbutton's startup and "New Identity" still succeed in opening control connections to 127.0.0.1. Edit: It'd probably be a good idea to verify this on platforms other than Linux.

Edit 2: It occurs to me that the CUPS interface at http://127.0.0.1:631, which has had multiple CSRF issues in the past, can instruct cupsd to connect to remote hosts in all kinds of ways. So in addition to fingerprinting open ports by measuring timeouts, there's potential for direct deanonymization.

Last edited 4 years ago by cypherpunks (previous) (diff)

comment:5 Changed 4 years ago by oc

If I understand correctly, this ticket is about evaluating localhost fingerprinting risks, which is all good. #10686 was about considering any clear-text request to localhost a breach to TBB's proxy obedience requirement (disregarding whether good fingerprinting can be achieved or not). The difference becomes obvious when one considers CUPS, or any other HTTP service may run on TBB's host.

Max Jacob Maass has put up a test page:

comment:6 Changed 4 years ago by cypherpunks

Noscript already provides a functionality to prevent this kind of scenario :

The following ABE rule prevents loading any local resource from a remote page :

...
# This one guards the local network, like LocalRodeo
# LOCAL is a placeholder which matches all the LAN 
# subnets (possibly configurable) and localhost
Site LOCAL
Accept from LOCAL
Deny
...

comment:7 Changed 4 years ago by oc

Cc: oc added

comment:8 in reply to:  6 Changed 4 years ago by cypherpunks

(cyperpunks2 here)

Replying to cypherpunks:

Site LOCAL
Accept from LOCAL
Deny


Interesting. That way it's safe to conveniently administer CUPS etc. from inside Tor Browser. I like it.

With the rule already included in NoScript, TBB would only need to ship with noscript.ABE.enabled = true.

comment:9 in reply to:  5 ; Changed 4 years ago by gk

Replying to oc:

If I understand correctly, this ticket is about evaluating localhost fingerprinting risks, which is all good. #10686 was about considering any clear-text request to localhost a breach to TBB's proxy obedience requirement

Where is the breach, exactly? The design document says:

The browser MUST NOT bypass Tor proxy settings for any content.

And including "127.0.0.1" into "content" does not make any sense here as this would imply that TBB users could never access 127.0.0.1 themselves (I don't see how you can proxy 127.0.0.1 if your proxy is listening at 127.0.0.1 as well).

comment:10 in reply to:  9 Changed 4 years ago by cypherpunks

(cypherpunks2)

Replying to gk:

And including "127.0.0.1" into "content" does not make any sense here as this would imply that TBB users could never access 127.0.0.1 themselves (I don't see how you can proxy 127.0.0.1 if your proxy is listening at 127.0.0.1 as well).

So seperate from the fingerprinting issue, It would at least go against the spirit of that requirement if a website accessed through Tor Browser can tunnel a clearnet request through a commonly installed server running on 127.0.0.1, no?

So originally it was less a case of "proxying 127.0.0.1" than "denying unneccessary connections to 127.0.0.1", but it turns out NoScript ABE is superior in that it removes less functionality.

comment:11 in reply to:  9 Changed 4 years ago by oc

Replying to gk:

Where is the breach, exactly? The design document says:

The browser MUST NOT bypass Tor proxy settings for any content.

As I understand it, the idea behind proxy obedience is that all TBB generated traffic (DNS, HTTP, whatever) must go through Tor: nothing must be leaked. It is not (only) about verifying the socks proxy honors its settings.
As it is, according to users reports TBB does not leak on FreeBSD, but leaks on Linux (127.0.0.1) and Windows (LAN). Anyone can check this with the above mentioned test page -- further reports are welcome.
If these reports are right:

  • A remote server can discover what platform TBB is running on with at most two JS-embedded XHRs.
  • If there is a local web server with liberal CORS policies, the remote server can browse it and exfiltrate its data.
  • When XHRs fail because of CORS, it can be circumvented using other resources: successfully retrieving an <img src=http://127.0.0.1:631/images/cups-icon.png> will go around CUPS CORS policies, and tell with a good confidence that host OS is running CUPS (perhaps even what possible versions if icon has changed during CUPS history).

I'm willing to agree with you that the security issue may not be limited to proxy obedience. Perhaps there is another better reason to oppose such behavior?
Still, whatever it is, I believe that allowing TBB to browse, or even download resources (images, etc) from localhost or LAN is a security breach in itself: it allows fingerprinting and data evasion as shown above and offers roughly nothing in return.

Replying to gk:

And including "127.0.0.1" into "content" does not make any sense here as this would imply that TBB users could never access 127.0.0.1 themselves

Let's take it in reverse: why would anyone use TBB to browse localhost exactly?

Last edited 4 years ago by oc (previous) (diff)

comment:12 Changed 4 years ago by oc

Let's note that enforcing stricter standards than stock browsers is one of the reasons why TBB exists: for example, Linux stock FF will happily XHR to LAN (as will Chrome), whereas TBB will not.
We already have bent the W3C standard and gone further than CORS, for the better. Unfortunately, it seems this job is only half-done.

Last edited 4 years ago by oc (previous) (diff)

comment:13 Changed 4 years ago by mikeperry

Keywords: tbb-pref MikePerry201401R added
Status: newneeds_review

I think that oc is right about not needing to browse localhost from TBB. On top of that, I had assumed that the network.proxy.no_proxies_on setting applied to *all* XUL JS too, so I never bothered trying to remove it, thinking it was an obvious non-solution. In retrospect, it makes sense that it does not harm New Identity or anything else in TBB, because we use XPCOM socket interfaces for our extension-based localhost connections, and not nsIChannel.

I'm going to try driving TBB on Mac and Linux around without it and see if I notice anything. New Identity at least works fine on both here, too, though. Which is a good sign.

comment:14 in reply to:  13 ; Changed 4 years ago by gk

Replying to mikeperry:

I think that oc is right about not needing to browse localhost from TBB.

What about configuring CUPS from the browser? At least I am used to it. And the need for two browsers (a TorBrowser and, say, a vanilla Fx) bears the big risk that the users mess things up. So, if we see the need for removing "access" to 127.0.0.1 from the outside then we should make sure that the user itself is still able to reach things on 127.0.0.1 IMO.

comment:15 in reply to:  14 Changed 4 years ago by cypherpunks

(cypherpunks2)

Replying to gk:

Replying to mikeperry:

I think that oc is right about not needing to browse localhost from TBB.

What about configuring CUPS from the browser? At least I am used to it.


Now that you have said it out loud, I can confess to that, too. ;)

One twist is that a web server running on 127.0.0.1 can serve pages that include remote resources. Those would be proxied through tor, which on the one hand might be quite useful, but on the other hand might include identifying information. (I'm thinking something like http://stats.mediaserver-vendor.example.com/?hostname=whoops.) It's essentially the same problem as blindly torifying some off-the-shelf program.

To err on the side of safety, we could use ABE to also block remote requests originating from 127.0.0.1. Its language seems to have neither negation nor a GLOBAL keyword in opposition to LOCAL, but the rules are supposed to be processed in order. Therefor, this could work:

# Prevent Internet sites from requesting LAN resources.
Site LOCAL
Accept from LOCAL
Deny

# Prevent LAN sites from requesting Internet resources.
Site ALL
Deny from LOCAL

As prefs:

user_pref("noscript.ABE.enabled", true);
user_pref("noscript.ABE.rulesets.SYSTEM", "# Prevent Internet sites from requesting LAN resources.\nSite LOCAL\nAccept from LOCAL\nDeny\n\n# Prevent LAN sites from requesting Internet resources.\nSite ALL\nDeny from LOCAL");

Doesn't break anything here, however I don't have a local webserver embedding remote resources at hand.

Last edited 4 years ago by cypherpunks (previous) (diff)

comment:16 Changed 4 years ago by cypherpunks

(cypherpunks2)

Okay, so I did test it *phew* and it turns out that LOCAL only refers to RFC private addresses and not 127.0.0.1.

But the following does work fine:

# Prevent Internet and LAN sites from requesting 127.0.0.1's resources.
Site 127.0.0.1
Accept from 127.0.0.1
Deny

# Prevent 127.0.0.1 from requesting Internet and LAN resources.
Site ALL
Deny from 127.0.0.1

As prefs:

user_pref("noscript.ABE.enabled", true);
user_pref("noscript.ABE.rulesets.SYSTEM", "# Prevent Internet and LAN sites from requesting 127.0.0.1's resources.\nSite 127.0.0.1\nAccept from 127.0.0.1\nDeny\n\n# Prevent 127.0.0.1 from requesting Internet and LAN resources.\nSite ALL\nDeny from 127.0.0.1");
Last edited 4 years ago by cypherpunks (previous) (diff)

comment:17 in reply to:  16 ; Changed 4 years ago by oc

I'm discovering that we do not have the same user model:

  • I only use TBB for a few specific tasks, while everything else I do with a regular browser.
  • You are promoting TBB as the main/only browser, in which case CUPS (et al) should be accessible indeed.

Replying to cypherpunks:

# Prevent Internet sites from requesting LAN resources.
Site LOCAL
Accept from LOCAL
Deny
(...)
# Prevent 127.0.0.1 from requesting Internet resources.
Site ALL
Deny from 127.0.0.1

Your ABE rules seem to work ok here.
Can/should 127.0.0.1 access LOCAL though? I cannot tell nor check it myself because of other (related) problems:

  • LAN IPs are blocked anyway:
    [warn] Rejecting SOCKS request for anonymous connection to private address [scrubbed]
    
  • 127.0.0.1 works but localhost does not.

Am I the only one experiencing those?

Last edited 4 years ago by oc (previous) (diff)

comment:18 in reply to:  17 ; Changed 4 years ago by cypherpunks

(cypherpunks2)

Replying to oc:

Replying to cypherpunks:

# Prevent Internet sites from requesting LAN resources.
Site LOCAL
Accept from LOCAL
Deny
(...)
# Prevent 127.0.0.1 from requesting Internet resources.
Site ALL
Deny from 127.0.0.1

That's a strange mix? Only the ruleset from comment 16 is the good one.

Your ABE rules seem to work ok here.
Can/should 127.0.0.1 access LOCAL though?

It should not - according to the ABE documentation ALL is a "special token matching any URI". So 127.0.0.1 originating requests to LAN are to be blocked by the second rule. I've amended the rule comments, though blocking LAN should be redundant. (If it is not redundant because somehow Windows TB is able to connect to LAN IPs, that sounds like a material for a separate bug ticket.)

  • 127.0.0.1 works but localhost does not.

As expected, unless localhost is added to extensions.torbutton.no_proxies_on. In which case we'd also have to deal with localhost resolving to its IPv6 address? Not worth it IMHO.

Last edited 4 years ago by cypherpunks (previous) (diff)

comment:19 Changed 4 years ago by cypherpunks

(cypherpunks2)

Oh God, so Firefox considers alternative IP address representations (like 2130706433 for 127.0.0.1) equivalent and lets them through, while Noscript's ABE considers them to differ and thus the rules don't catch.

I like unsticking the printer queue without starting another browser as much as the next guy, but this is where one could start to lean towards saying fuck it, setting *.no_proxies_on="", and getting the hell outta Dodge.

Bonus Cut: tor as a client at least (not sure about the relay situation) actually tries to connect to these shitty-style IP addresses:

Have tried resolving or connecting to address '2130706433' at 3 different places. Giving up.

Can someone else please file the bug for that, I think I'm going to smash some Fabergé eggs now.

Last edited 4 years ago by cypherpunks (previous) (diff)

comment:20 in reply to:  18 Changed 4 years ago by oc

Replying to cypherpunks:

That's a strange mix? Only the ruleset from comment 16 is the good one.

Is it? Sorry, I thought you recommended comments 15 and 16 rules concatenated…
Note that my question was also: shouldn't 127.0.0.1 be allowed to access LOCAL? In other words, what is wrong with localhost CUPS fetching LAN resources?

blocking LAN should be redundant. (If it is not redundant because somehow Windows TB is able to connect to LAN IPs, that sounds like a material for a separate bug ticket.)

If you get rid of LOCAL rules (comment 15), a webserver on LAN could XHR to its WAN address and learn what your Tor exit node is, for example, couldn't it?

Last edited 4 years ago by oc (previous) (diff)

comment:21 in reply to:  14 ; Changed 4 years ago by mikeperry

Replying to gk:

Replying to mikeperry:

I think that oc is right about not needing to browse localhost from TBB.

What about configuring CUPS from the browser? At least I am used to it. And the need for two browsers (a TorBrowser and, say, a vanilla Fx) bears the big risk that the users mess things up. So, if we see the need for removing "access" to 127.0.0.1 from the outside then we should make sure that the user itself is still able to reach things on 127.0.0.1 IMO.

It is called the "Tor Browser". I don't think we should really support things like using it to configure local services, especially at the expense of excessive complexity, increased vulnerability surface, or increased fingerprinting.

I can see the development utility of running TBB tests on an http server listening on 127.0.0.1, but such developers/testing frameworks are quite capable of explicitly allowing 127.0.0.1 in the pref.

The better question is "does CUPS printing work at all if we remove 127.0.0.1 this pref?"

comment:22 in reply to:  21 Changed 4 years ago by oc

Replying to mikeperry:

It is called the "Tor Browser". I don't think we should really support things like using it to configure local services, especially at the expense of excessive complexity, increased vulnerability surface, or increased fingerprinting.

That's also how I understood proxy obedience being at the top of the requirements list. That is why I put it up in the first place: if I interpret it correctly, we do not even have to look for a better/smarter solution than blocking all non-tor connections (local or not).
Perhaps the design documents should explicitly state what is TBB's policy regarding local non-Tor connections -- or do they already?

Replying to mikeperry:

The better question is "does CUPS printing work at all if we remove 127.0.0.1 this pref?"

It does work here, with all 127.0.0.1 traffic blocked (ABE).

Replying to cypherpunks:

Okay, so I did test it *phew* and it turns out that LOCAL only refers to RFC private addresses and not 127.0.0.1.

On my Linux box:

Site LOCAL
Deny

…is enough to block 127.0.0.1 traffic. Is this another platform-specific behavior?

Last edited 4 years ago by oc (previous) (diff)

comment:23 Changed 4 years ago by oc

In the meantime, exploring smarter safe policies: Yuri has theorized cross-network policies in a general browser context:

CORS http://www.w3.org/TR/cors/ talks how server can accept or not accepr cross-origin requests using special http headers. However, this should only apply only from narrower to wider network direction. So it should apply for global->global, or LAN->global, or loopback->LAN, etc.
But cross-origin should never be allowed in these situations: global->LAN, global->loopback, LAN->loopback.
Browser should have special rule disallowing such cross-origin access as security violation.

In a TBB context we might want to enforce strictly hermetic network boundaries:

  • block narrower-to-wider as well (eg LAN->global may leak your Tor exit node)
  • but still allow same-network traffic: lo->lo, LAN->LAN, WAN->WAN

What do you think?

Last edited 4 years ago by oc (previous) (diff)

comment:24 Changed 4 years ago by oc

To further develop the above proposal, or present it a bit differently, we have two classes of traffic and two corresponding network zones: Tor (WAN) and non-Tor (lo/LAN).
Tor anonymity mandates that we at least burn all bridges between these two worlds, otherwise we cannot protect users from fingerprinting or other information leakage, whether it's initiated from the inside or the outside, accidental or hostile.

When using TBB to browse inside non-Tor zones (lo/LAN), that is as a regular un-proxied web browser, TBB may not need to enforce anything a regular browser wouldn't: if TBB blocks some traffic, chances are users will switch to another browser and be vulnerable all the same anyway.
So, it seems TBB could allow W3C-compliant traffic rules (ie CORS) inside the non-Tor zone, and live with lo->LAN leakage in particular. Safety issues with LAN->lo intrusions should probably be fixed upstream as Yuri advocates: with a browser-level ban on wider-to-narrower traffic.
If ever, this is not going to happen any time soon, though: Chrome dev says they would require updated W3C specs first; FF dev seems happy with CORS only too, probably for the same legitimate reason. In the meantime, TBB could use default ABE rules to block it anyway.

Altogether:

# Block wider-to-narrower access to loopback
Site 127.0.0.1
Accept from 127.0.0.1
Deny

# Isolate Tor vs non-Tor zones
# Block WAN -> LAN/lo (intrusion)
Site LOCAL
Accept from LOCAL
Deny
# Block LAN/lo -> WAN (leakage)
Site ALL
Deny from LOCAL
Accept

Practical difference with previous post proposal (hermetic network boundaries) is that lo->LAN leakage isn't blocked anymore, in order to preserve as much of the W3C specs spirit as possible.

From what I understood from users reports, these ABE rules should work as expected on all platforms. However other platform specificities or LAN addressing schemes might currently prevent local browsing anyway: LAN traffic is blocked by the SOCKS proxy as a default on Linux at least, 127.0.0.1 is blocked on FreeBSD.

Last edited 4 years ago by oc (previous) (diff)

comment:25 in reply to:  24 ; Changed 4 years ago by cypherpunks

(cypherpunks2)

Replying to oc:

these ABE rules should work as expected on all platforms.


Our postings yesterday overlapped, please see #comment:19 for why NoScript ABE cannot work.

comment:26 in reply to:  25 ; Changed 4 years ago by oc

Replying to cypherpunks:

Our postings yesterday overlapped, please see #comment:19 for why NoScript ABE cannot work.

I'm not sure I get what you meant with #comment:19 indeed. Perhaps it's because on my machine, a 127.0.0.1 ABE rule does catch 2130706433?

PS: How come we seem to repeatedly experience so wildly different TBB behaviors? That's pretty fishy, isn't it?

Last edited 4 years ago by oc (previous) (diff)

comment:27 in reply to:  26 ; Changed 4 years ago by cypherpunks

(cypherpunks2)

Replying to oc:

on my machine, a 127.0.0.1 ABE rule does catch 2130706433?


It looks as if Noscript normalizes IP addresses only when they are matched to "Site x.x.x.x" directives, but not when they are matched to predicates e.g. "Deny from x.x.x.x".

If I test the second rule from comment 16 with a local webserver serving a page including a remote image, the image loads when accessing the server through 127.0.0.1, but not when accessing it through 2130706433.

However a flat out

Site 127.0.0.1
Deny

means I cannot access the server itself through either address, which is what you may have tested.

Last edited 4 years ago by cypherpunks (previous) (diff)

comment:28 Changed 4 years ago by mikeperry

I want to avoid NoScript ABE policies if at all possible. Does completely emptying network.proxy.no_proxies_on break CUPS? Or printing on any other platform? I don't use CUPS.

comment:29 in reply to:  28 Changed 4 years ago by cypherpunks

cypherpunks2

Replying to mikeperry:

Does completely emptying network.proxy.no_proxies_on break CUPS?


Not on my Linux system

comment:30 in reply to:  27 Changed 4 years ago by oc

Replying to cypherpunks:

It looks as if Noscript normalizes IP addresses only when they are matched to "Site x.x.x.x" directives, but not when they are matched to predicates e.g. "Deny from x.x.x.x".

Got it, thanks! That explains a lot indeed…
Sorry for the noise.

comment:31 in reply to:  28 Changed 4 years ago by mo

Replying to mikeperry:

I want to avoid NoScript ABE policies if at all possible. Does completely emptying network.proxy.no_proxies_on break CUPS? Or printing on any other platform? I don't use CUPS.

You cannot break printing or CUPS, all TBB could block is access to the local CUPS web admin panel from inside TBB (create/edit/delete printers). I don't see why people can't use a second browser for local web services. CUPS via web is so 1990s and ugly, any "beginner" uses a GUI to configure their printers. To me, it sounds simpler and safer to just disable any localhost access from within the browser, and one should not have to rely on an extension to take care of it.

comment:32 Changed 4 years ago by cypherpunks

  1. This fix can't to prevent fingerprinting for environment where Torbrowser used without proxy, like Transparent proxy or something.
  2. Tor is not nanny to control what does Torbrowser and it depends ClientRejectInternalAddresses option, yet it loudly yells to user because it's bug to surf localhost over Tor.

If you want to deny localhost connection attempts then find way to deny it actually without reinventing any security holes.

It especially fun with fix for #10682.

comment:33 Changed 4 years ago by cypherpunks

Priority: majorcritical
Status: needs_reviewnew
Type: taskdefect

comment:34 Changed 4 years ago by gk

Resolution: fixed
Status: newclosed

This is actually fixed in the upcoming release (3.5.2). The fix in Torbutton is in 3d84b2ada3389899d324223007f7a29ef6b90a17.

comment:35 Changed 4 years ago by cypherpunks

It's not fix, it's security hole.

comment:36 Changed 4 years ago by cypherpunks

Previously I've been able to glue the 1Password extension into TBB (not supported by the 1P folks, but it worked, see post here and post linked in that post). That appears to no longer work. I'm not certain, but I wonder if this fix is what's blocking it (the 1P extension uses Websocket connections to 127.0.0.1 to communicate with a helper process, see here). Could that be the case? Life without 1P ready-to-hand in the browser is going to be a pain.

Last edited 4 years ago by cypherpunks (previous) (diff)

comment:37 in reply to:  36 ; Changed 4 years ago by gk

Replying to cypherpunks:

Previously I've been able to glue the 1Password extension into TBB (not supported by the 1P folks, but it worked, see post here and post linked in that post). That appears to no longer work. I'm not certain, but I wonder if this fix is what's blocking it (the 1P extension uses Websocket connections to 127.0.0.1 to communicate with a helper process

I think so, yes. To add an exception click on the green onion icon in your toolbar -> Preferences... -> Use custom proxy settings -> No Proxies for: AND there enter "127.0.0.1". Then, clicking on "OK" should fix your problem. But be aware that you might stand out more than other TBB users as a result of that.

comment:38 Changed 4 years ago by gk

Or just add "127.0.0.1" to the *no_proxies_on preferences in about:config...

comment:39 in reply to:  37 Changed 4 years ago by cypherpunks

Replying to gk:

Replying to cypherpunks:

Previously I've been able to glue the 1Password extension into TBB (not supported by the 1P folks, but it worked, see post here and post linked in that post). That appears to no longer work. I'm not certain, but I wonder if this fix is what's blocking it (the 1P extension uses Websocket connections to 127.0.0.1 to communicate with a helper process

I think so, yes. To add an exception click on the green onion icon in your toolbar -> Preferences... -> Use custom proxy settings -> No Proxies for: AND there enter "127.0.0.1". Then, clicking on "OK" should fix your problem. But be aware that you might stand out more than other TBB users as a result of that.

Thanks, making that change that does enable the 1Password extension to work again. Thanks also for noting the potential fingerprinting tradeoff. After I made the change, I tried Jacob Maas' test page (linked in comment 5 above) with the ports 1Password uses, and each one was reported "closed or error during testing", which sounds comforting though I don't have the expertise to know how much it actually is.

comment:40 Changed 3 years ago by proper

connections to 127.0.0.1 no longer possible: #11493

Note: See TracTickets for help on using tickets.