Closed Bug 1684241 Opened 4 years ago Closed 4 years ago

No SOCKSv5 proxy for 127.0.0.0/8

Categories

(Core :: Networking, defect)

Firefox 84
defect

Tracking

()

RESOLVED FIXED
86 Branch
Tracking Status
firefox-esr78 --- unaffected
firefox84 --- wontfix
firefox85 - wontfix
firefox86 --- fixed

People

(Reporter: regmeplease, Assigned: emk)

References

(Regression)

Details

(Keywords: regression)

Attachments

(1 file)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0

Steps to reproduce:

Firefox v8.4.1 (Windows 10 and Arch Lilnux).

  1. Create two SOCKSv5 proxies via SSH (Windows: putty v0.74, Linux: openssh-8.4p1) with: "-D 127.0.0.1:1080 -D 127.1.2.3:1080"
  2. Configure Firefox SOCKSv5 manual proxy with either address, leave empty any other setting.

Actual results:

  1. Browsing to "https://www.ipify.org/" shows the proxy is actually working
  2. Browsing to a remote web UI listening on 127.0.0.42:9091 doesn't work and gives this error:
    Unable to connect

Firefox can’t establish a connection to the server at 127.0.0.42:9091.
I can read that "Connections to localhost, 127.0.0.1, and ::1 are never proxied", but 127.0.0.42 is a different IP.

Expected results:

The remote web UI should have been shown.
This has always worked until last week or so.

On the remote (linux) system I can see the web UI on specified IP:port :

[support@s1 ~] nmap -A -p 9091 127.0.0.42

Starting Nmap 7.60 ( https://nmap.org ) at 2020-12-26 11:47 CET
Nmap scan report for 127.0.0.42
Host is up (0.000090s latency).

PORT STATE SERVICE VERSION
9091/tcp open http Transmission BitTorrent management httpd (unauthorized)
| http-auth:
| HTTP/1.1 401 Unauthorized\x0D
|_ Basic realm=Transmission
|_http-server-header: Transmission
|_http-title: Site doesn't have a title (text/html; charset=ISO-8859-1).

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 16.48 seconds

Bugbug thinks this bug should belong to this component, but please revert this change in case of error.

Component: Untriaged → Networking
Product: Firefox → Core

Hi Reporter,

Since this looks like a recent regression, could you help us by using mozregression to find out the problem?

Thanks.

Flags: needinfo?(regmeplease)

I think it's in the networking area.
The proxy is working for all addresses but the ones within the 127.0.0.0/8 subnet.
It should work for anything but 127.0.0.1 as it used to di until some time ago.
I have no idea on how mozregression works and am also afraid i cannot tell which version was last working.
Will try, though.

Flags: needinfo?(regmeplease)

I am not allowed to even run the mozregression installer on my Windows machine because, I think, it's trying to install system-wide software and not only for my user.
It fails like this:
Output folder: C:\Program Files (x86)\mozregression-gui
Create folder: C:\Program Files (x86)\mozregression-gui
Can't write: C:\Program Files (x86)\mozregression-gui\MSVCP140.dll

This is a showstopper for Windows debugging in my case as I don't have another Windows machine.
Will try on my (Arch) Linux system later.

TBH, I think that the change that triggered this bug/regression is in the proxy part, the one handling the "No proxy for" filtering.
And I think there shouldn't have been many changes in that area lately.

You should also try this version on your windows: https://github.com/mozilla/mozregression/releases/tag/gui-0.9.46
Hopefully, this one will install and you could help us determine the regressor. Let me know if you need help.

Alternatively, if you would be so kind as to give me exact steps to reproduce, I could attempt to investigate for the regressor myself.
Thank you for your contribution!

Flags: needinfo?(regmeplease)

We actually disallow proxying all connections to 127.0.0.0/8 ranges:
https://searchfox.org/mozilla-central/rev/014fe72eaba26dcf6082fb9bbaf208f97a38594e/netwerk/base/nsProtocolProxyService.cpp#1102
https://searchfox.org/mozilla-central/rev/014fe72eaba26dcf6082fb9bbaf208f97a38594e/dom/security/nsMixedContentBlocker.cpp#252
https://searchfox.org/mozilla-central/rev/014fe72eaba26dcf6082fb9bbaf208f97a38594e/netwerk/dns/DNS.cpp#160

Workaround: flip network.proxy.allow_hijacking_localhost.

I think this is a message problem. The message should be "Connections to localhost, 127.0.0.0/8, and ::1 are never proxied".

Regressed by: 1507110

@Masatoshi thanks for the insight and the workaround.

127.0.0.1 and ::1 represent a single IP address which is otherwise called localhost.
127.0.0.0/8 and ::1/128 are subnets.
The change in the behaviour, dating back to several years, has a rather big impact,
especially when paired with SOCKS proxy, IMHO, and has no actual reason to be.

Flags: needinfo?(regmeplease)

You marked as a regression from 67, but the reporter here seems to indicate this worked until very recently. From a very very quick look at hg blame, is it possible bug 1220810 regressed (or deliberately changed) something here in how we treat the subnet, as that is new for 84?

(this is also why running mozregression would be helpful to confirm exactly what broke; though failing that, confirmation of when this last worked would be useful...)

Flags: needinfo?(VYV03354)
Flags: needinfo?(VYV03354)
No longer regressed by: 1507110

I don't make use of that feature quite often but I would bet that it has been working until beginning of December 2020.
And it has worked since March 2016, maybe even earlier.
127.0.0.1 wasn't being proxy-ed through, this is why I moved remote service from 127.0.0.1 to 127.0.0.42.
And that has been working.

Masatoshi's suggestion worked the problem around clearly pointing at the the core issue.
In my personal opinion, implicit exemptions, even when documented, should be avoided:
once I use a proxy I want everything to be proxy-ed.
If I need 127.0.0.1 or 127.0.0.0/8 not to be proxy-ed, than I have that friendly proxy setting for any exemption I want.

If you really need more detailed directions than those I wrote in the original reporting message, please let me know and I will provide full details as a step-by-step procedure.

[Tracking Requested - why for this release]:

(In reply to Uqbar from comment #10)

In my personal opinion, implicit exemptions, even when documented, should be avoided:
once I use a proxy I want everything to be proxy-ed.

Just to note that the original exception for localhost (in Firefox 67 and later, ie a few years back) was added because of a security issue with auto-discovered proxy settings, see bug 1503393. That is, it turns out that in practice the web browser cannot just assume that the proxy existing really means that [the user] "wants everything to be proxy-ed", including localhost. Chrome did the same kind of thing for the same reason: https://bugs.chromium.org/p/chromium/issues/detail?id=899126 .

Whether this same issue would exist for the other IPs in this subnet, I don't know, but our network team should be able to clarify.

If I need 127.0.0.1 or 127.0.0.0/8 not to be proxy-ed, than I have that friendly proxy setting for any exemption I want.

(In reply to Masatoshi Kimura [:emk] from comment #6)

I think this is a message problem. The message should be "Connections to localhost, 127.0.0.0/8, and ::1 are never proxied".

Right; if the broadening of the exception here to this entire subnet was intentional and is necessary, we should update the message in the connection dialog, ie we'd need to update https://searchfox.org/mozilla-central/rev/014fe72eaba26dcf6082fb9bbaf208f97a38594e/browser/locales/en-US/browser/preferences/connection.ftl#69 (and change the string ID so it gets retranslated, and update the reference to it in connection.xhtml ). Happy to review a patch for that; I'm not really an expert on our networking setup, that sec bug, and whether the entire subnet needs exempting here or not. It looks like there is already a discussion around this in the last few comments in bug 1220810.

Going to set some tracking flags given the comments in bug 1220810 suggesting this is not an isolated incident, and we missed the goal of aligning with Chrome.

Has Regression Range: --- → yes

I am not in favor of adapting the message to new different behaviours, though.
Because I don't see it as necessary to go from 127.0.0.1/32 to 127.0.0.0/8.

If a user wants everything to be proxy-ed, then let her do it via proxy options.
If a user wants to add any exemption, then let her do it via the proxy options.

I am in favor of bringing back previous behaviour (and previous message).
Or adding that "loopback hijack" option among other proxy options.

Finally, aligning with chrome is something new to me. I choose Firefox because it's different, not because it's the same as <you name it>.
But this is philosophy, far beyond the technical scope of this report.

Apparently Chrome uses different rules between proxy bypass and DNS resolution (if their document is correct).

Here is their source code:
https://source.chromium.org/chromium/chromium/src/+/master:net/proxy_resolution/proxy_bypass_rules.cc;drc=71698e610121078e0d1a811054dcf9fd89b49578;l=238

  return IsLocalhost(url) || IsIPv4MappedLoopback(url) ||
         IsLinkLocalIP(url)

https://source.chromium.org/chromium/chromium/src/+/master:net/base/url_util.cc;drc=7ccffaf0933ccc647c744bf66971bcf5f33a676a;l=376

bool IsLocalhost(const GURL& url) {
  return HostStringIsLocalhost(url.HostNoBracketsPiece());
}

bool HostStringIsLocalhost(base::StringPiece host) {
  IPAddress ip_address;
  if (ip_address.AssignFromIPLiteral(host))
    return ip_address.IsLoopback();
  return IsLocalHostname(host);
}

https://source.chromium.org/chromium/chromium/src/+/master:net/base/ip_address.cc;drc=7ccffaf0933ccc647c744bf66971bcf5f33a676a;l=270

bool IPAddress::IsLoopback() const {
  // 127.0.0.1/8
  if (IsIPv4())
    return ip_address_[0] == 127;

So our current bypass rule regarding IPv4 loopback address matches Chrome. I'll attach a patch to update the message.

The actual main piece of code is: (sorry, I don't know how to do rich text):

bool ProxyBypassRules::MatchesImplicitRules(const GURL& url) {
// On Windows the implict rules are:
//
// localhost
// loopback
// 127.0.0.1
// [::1]
// 169.254/16
// [FE80::]/10
//
// And on macOS they are:
//
// localhost
// 127.0.0.1/8
// [::1]
// 169.254/16
//
// Our implicit rules are approximately:
//
// localhost
// localhost.
// *.localhost
// loopback [Windows only]
// loopback. [Windows only]
// [::1]
// 127.0.0.1/8
// 169.254/16
// [FE80::]/10
return IsLocalhost(url) || IsIPv4MappedLoopback(url) ||
IsLinkLocalIP(url)
#if defined(OS_WIN)
// See http://crbug.com/904889
|| (url.host_piece() == "loopback") ||
(url.host_piece() == "loopback.")
#endif
;
}

Chrome defines its own rules "aproximately"'.
Firefox wants to mimic Chrome and breaks its long term behavior.
Changing the message is the easy path, indeed.
I would add some code to make an easy access to the "loopback hijack" feature, though, to restore the original historic behavior.

Note that the "Windows" list refers WinInet (read: IE). Chromium based Edge will behave just like Chrome.

Assignee: nobody → VYV03354

I see from the code that while for IPv4 you are going to exempt the whole 127.0.0.0/8, a subnet, for IPv6 you would exempt a single address, that is ::1, and not the whole loopback subnet, that is ::1/128.
Does this make any sense?

My bad! ::1/128 is a single IPv6.

Pushed by VYV03354@nifty.ne.jp:
https://hg.mozilla.org/integration/autoland/rev/5dbc5c9a3d38
Update a message to align with the actual proxy bypass range. r=Gijs,fluent-reviewers,preferences-reviewers

Confirming it based on the latest comments.

Status: UNCONFIRMED → NEW
Ever confirmed: true

Given the outcome here is a string change, I assume this is wontfix for 85.

Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → 86 Branch
See Also: → 1711303
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: