incorrectly reusing an already open http2 connection to a host resolved to multiple ips, for another host resolved to a single ip among the former, but NOT the one the connection is already made to

RESOLVED INVALID

Status

()

RESOLVED INVALID
a year ago
a year ago

People

(Reporter: m.stoikov, Unassigned)

Tracking

55 Branch
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

a year ago
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0
Build ID: 20170626235638

Steps to reproduce:

A repo with docker-compose setup is available at https://github.com/MStoykov/firefox-redirect-bug with additional instructions and info

Let say common.example.com is resolved to two ips 172.129.0.5 and 172.129.0.102 and specific1.example.com is resolved to 172.129.0.5 (the first ip) and specific2.example.com to 172.129.0.102 (the second ip)

All servers support http2 and are well configured. and all servers redirect from the common domain to the "specific" ones of the other server (172.129.0.5 will redirect to specific2 and 172.129.0.102 to specific1). But each server responds with 200 for their "specific" domain.

We make request for https://common.example.com/file  in firefox




Actual results:

When firefox makes request for https://common.example.com/file it makes it to 172.129.0.5, which responds with 302 redirect to https://specific2.example.com/file. 
Firefox reuses the connection to 172.129.0.5



Expected results:

Firefox should make new connection to 172.129.0.102
Component: Untriaged → Networking: HTTP
Product: Firefox → Core
This is by design. HTTP/2 connection reuse explicitly allows this case (DNS records for the two hostnames overlap, and the server presents a certificate valid for both hostnames). If you wish to prevent connection reuse like this, please use HTTP status 421 (Not Authoritative). See https://tools.ietf.org/html/rfc7540#section-9.1.1 for more details.
Status: UNCONFIRMED → RESOLVED
Last Resolved: a year ago
Resolution: --- → INVALID
(Reporter)

Comment 2

a year ago
I think the title (which I tried very much to make as short and descriptive as possible) might've misrepresented the issue. 

The real situation is we shard multiple files between many machines. One file is only on one machine. All servers given a file path, can calculate from which server the file should be served. All servers have a specific domain which only resolve to one ip - theirs. There is also a common domain which resolves to the ips of all machines. 
The situation is firefox makes a connection for the common domain and hits a machine with ip 172.129.0.5 and asks for '/file', but the file should not be served from there, so we use 302 redirect to 'specific2.example.com' which resolves to ONLY '172.129.0.102'. Firefox does NOT have a connection to that ip and should at this point make a new connection to it and make a new get request over it. Instead it reuses the connection to 172.129.0.5.

After much reading of the linked section 9.1.1 I'm positive, firefox is not acting according with the rfc. The last sentence of the first paragraph explicitly says 'For TCP connections without TLS, this depends on the host having resolved to the same IP address.'. Everything after that only adds on top of that for https connections.

The linked repo very well and 100% of the time demonstrates the issue. I highly recommend taking a look and trying it with a debug version of firefox and wireshark. 

Additionally, as I wrote in 'Specifics found so far:' section in the repo's README: a second connection is sometimes (practically always) made to the correct IP, after the 302 and the dns response is received. It's never use probably because a request for the file is made and received from the (IMO) wrongly reused first connection, before it is fully established.

If the servers are made to return 421 instead of 404, the correct file is served by firefox, BUT in the developer networks panel only the responses with 302 and 421 are shown. Wireshark shows that the connection to the correct ip is started (as previously) before the 421 response, but this time it's used to get the file as well.
Status: RESOLVED → UNCONFIRMED
Resolution: INVALID → ---
(Reporter)

Updated

a year ago
Summary: 302 redirect on an http2 connection from a domain with multiple ips to another domain resolved to a single of first ip is not followed correctly → incorrectly reusing an already open http2 connection to a host resolved to multiple ips, for another host resolved to a single ip among the former, but NOT the one the connection is already made to
Since the redirection target is explicitly specified as it's unique name instead of common name, it makes sense not to re-use the connection when the IP is different?
Flags: needinfo?(hurley)

Comment 4

a year ago
Hi,
I closed this bug first, and please feel free to open this bug. 
Thanks!
Status: UNCONFIRMED → RESOLVED
Last Resolved: a year agoa year ago
Resolution: --- → INCOMPLETE
(Reporter)

Comment 5

a year ago
The bug is still there. And as far as our testing went it's from at least firefox 52.0 onward.
(Reporter)

Updated

a year ago
Status: RESOLVED → UNCONFIRMED
Resolution: INCOMPLETE → ---
As you noted in comment 2, status 421 makes this behave as expected (which is exactly what it was designed to do). If both your common domain and your specific domains have DNS overlaps (which they do, as you noted in comment 0) and the cert presented by the common domain also covers the specific domains (which it does in your example, as it's a wildcart cert) then that is enough for coalescing to happen, perfectly allowed by 9.1.1. You have a way to ensure the appropriate host usage for just such a setup as you have (421).

I should note, that if you don't expect a specific server to be able to respond to requests for a particular hostname, it probably shouldn't be presenting a cert valid for that hostname.

This bug is still invalid.
Status: UNCONFIRMED → RESOLVED
Last Resolved: a year agoa year ago
Flags: needinfo?(hurley)
Resolution: --- → INVALID
(Reporter)

Comment 7

a year ago
RFC 9.1.1. specifically says 'For TCP connections without TLS, this depends on the host having resolved to the same IP address.' and then continues with 'For "https" resources, connection reuse additionally depends on ...' which IMO means that first the ip should be the same and then https connections should additionally check that the connection is already with an appropriate certificate. 

Status 421 might be fixing the issue but that doesn't mean that the issue should take arise in the first place.
You need to log in before you can comment on or make changes to this bug.