HSTS doesn't work for non-default ports

RESOLVED WORKSFORME

Status

()

Core
Networking
RESOLVED WORKSFORME
7 years ago
7 years ago

People

(Reporter: dveditz, Assigned: geekboy)

Tracking

Trunk
Points:
---

Firefox Tracking Flags

(blocking2.0 betaN+)

Details

(Reporter)

Description

7 years ago
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 :-)
(Reporter)

Updated

7 years ago
blocking2.0: --- → ?

Comment 1

7 years ago
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.
(Reporter)

Comment 2

7 years ago
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+
(Assignee)

Comment 4

7 years ago
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
(Reporter)

Comment 5

7 years ago
> 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
Last Resolved: 7 years ago
Resolution: --- → WORKSFORME
(Reporter)

Comment 6

7 years ago
It's possible John was in Private Browsing mode, where we don't save state, bug 557598.

Comment 7

7 years ago
(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.
You need to log in before you can comment on or make changes to this bug.