Closed Bug 613645 Opened 14 years ago Closed 14 years ago

HSTS doesn't work for non-default ports

Categories

(Core :: Networking, defect)

defect
Not set
normal

Tracking

()

RESOLVED WORKSFORME
Tracking Status
blocking2.0 --- betaN+

People

(Reporter: dveditz, Assigned: geekboy)

Details

Current Minefield supports HSTS only for the default port. John Wilander wrote that he tried 1. Access http://localhost.customer.se:8080 to see that it works 2. Access https://localhost.customer.se:8443 which includes a Strict-Transport-Security: max-age=10 which should give me 10 seconds to test that the browser enforces the policy. 3. Access http://localhost.customer.se:8080 to see that the browser switches to https://localhost.customer.se:8080 ...with the result that no URL rewriting was performed. The above steps surprised me, I would have expected that a server on port 8443 setting the header would only apply to the server on port 8443. But re-reading the spec--which could have made this clearer--it seems to say that a server using secure transport on any port that turns on HSTS turns that into a HSTS host on all ports. For instance, 7.2. URI Loading Whenever the UA prepares to "load", also known as "dereference", any URI where the host production of the URI [RFC3986] matches that of a Known HSTS Server [then replace the scheme] In URI specs the "host production" is definitely distinct from the port portion. Either way, our implementation matches neither the spec nor the way I think the spec should be written :-)
blocking2.0: --- → ?
Using HSTS on any port turns on HSTS for the entire host. This is because of the goofy cookie scoping rules. HTTP on port N should get redirected to HTTPS on port N, except that HTTP on port 80 should be redirected to HTTPS on port 443.
consensus on the HASMAT (excuse me, websec) ietf list is that it applies to all ports on the entire host.
I think we want this for Firefox 4 for a more consistent HSTS story.
blocking2.0: ? → betaN+
Can we detail the intended behavior? From what I understand, we want it to do this: http://stshost.tld:80 -> https://stshost.tld:443 http://stshost.tld:8080 -> https://stshost.tld:8080 For an STS host "stshost.tld": * If the resource is being requested via HTTP and on a NONstandard port, the port is not changed but the protocol is changed to HTTPS. * If the resource is being requested on a STANDARD port 80, the port is changed to 443 and the protocol is changed to HTTPS. For any non-STS host, the port and scheme are left unchanged by HSTS. HSTS headers are honored when encountered over the HTTPS protocol on any port. If this is the intended behavior, that's currently what our implementation does. This is consistent with the experience reported in comment 0. The spec 7.2 says: Whenever the UA prepares to "load", also known as "dereference", any URI where the host production of the URI [RFC3986] matches that of a Known HSTS Server [then replace the scheme] This means, rewrite the scheme, not the port for any host that has said "I want to be an HSTS host". Default ports are exempt from this since they're usually absent from the URI. See nsHttpChannel::AsyncRedirectChannelToHttps() http://mxr.mozilla.org/mozilla-central/source/netwerk/protocol/http/nsHttpChannel.cpp#1363 and nsHttpChannel::ProcessSTSHeader() http://mxr.mozilla.org/mozilla-central/source/netwerk/protocol/http/nsHttpChannel.cpp#908
> If this is the intended behavior, that's currently what our implementation > does. This is consistent with the experience reported in comment 0. It's NOT consistent with comment 0, but in testing I do not see the bug as reported. From a user-visible POV the address bar is not rewritten until the page loads so if you get an error it may stay "http://" -- but you'll generally get an ssl_error_rx_record_too_long if it's an insecure HTTP server so we're clearly trying to connect via SSL. Worksforme.
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → WORKSFORME
It's possible John was in Private Browsing mode, where we don't save state, bug 557598.
(In reply to comment #4) > Can we detail the intended behavior? From what I understand, we want it to do > this: > > http://stshost.tld:80 -> https://stshost.tld:443 > http://stshost.tld:8080 -> https://stshost.tld:8080 Agreed. At least I believe this is the intent of the spec. JeffH agreed to clear this up slightly in the language, but you are expressing the desired behavior.

Okay, but that can't work. Either the port is speaking HTTP, or it's speaking HTTPS. If the port is actually configured to redirect http://server:8080/ to https://server:8443/ , it speaks HTTP, and if the browser rewrites it to https://server:8080/ you're just going to get a protocol error.
So what this system needs is a consistent port mapping convention; like if the http: url has a port number we map it to some other known port number. Then you can have an actual port using http to redirect to the destination, and make it work the same as a browser that is doing
internal port mapping. Since the urls without the port numbers implicitly add (443 - 80) = 363, perhaps the convention should be to
always add 363 to the port number when changing it from http: to https:.

I tried :

In third step, why does Firefox load the HTTP page instead of going to HTTPS directly?

It seems HSTS is ignored. It also does not match behavior described in comment 0.

I use Firefox 105.0.3 64 bit on Windows 10.

Is this a regression? Bug? Intended?

You need to log in before you can comment on or make changes to this bug.