I’m not talking about why the client does want the upgrade…

Perhaps it doesn’t know if port 443 uses TLS or hosts the same content. In 
general it is just a lucky guess that it does have the same content. The 
Alt-Svc spec might help here, but currently this still requires the admin to 
configure things… and I don’t see that change anytime soon. (And if it would be 
automatic, it would still assume no firewalls, certificate availability, etc., 
etc.)


What I’m trying to say is: we should not just deny connections an upgrade for 
no reason. If we can upgrade the connection with a body… why explicitly deny it 
*after* we already received the body? If we want to reuse the connection we 
have to read the body anyway.


We can’t make the connection more secure by asking the client to retry the 
request… We can only make things less secure that way.


Returning a 4XX error just makes the client retry the request (perhaps after 
asking the user). The 4XX will be more work for the server, more work for the 
client and perhaps even for the end user.

We don’t make the web more secure by denying upgrades after the request is 
already sent. And as http/1.1 doesn’t have a way to stop a request before it is 
sent without resetting the connection I would say that we upgrade to TLS and/or 
H2c whenever possible.

The server can’t decide if the client should send the request unencrypted or 
not *after* it is already on the wire unencrypted.

By not upgrading we *as server* decide that the next request on the same 
connection will be unencrypted as well… By returning a 4XX (or other error) we 
ask the client to retry again; most likely on the same connection and just as 
unencrypted as the previous request.

On disconnecting we do the same thing….

The only way to ensure encryption or more advanced protocol support is honoring 
the upgrade request as soon as possible.

The deadlock scenarios on bodies that can’t be sent while the request is read 
are no reason to just block upgrades… These same deadlocks can occur for dozens 
of different reasons and in case of h2 even after upgrade. (Don’t send window 
updates and everything stalls… by design). At that point we can handle the 
error, just like how we handle timeouts on http/1.1

With h2 we can even force stream 1 (the response for the upgraded request) to 
close with an appropriate stream error in that case… so we can still reuse the 
connection.


With h2 you can in theory start the response in h2 while you are still reading 
the http/1.1 body, while with TLS you can’t as you need a two way handshake.

There will be cases where the upgrade path definitely breaks (e.g. 
huge/infinite chunked request echoed as response), but I think in most cases it 
can succeed without a problem. Just returning an error in easy cases for 
consistency with the cases where it can’t work doesn’t really help.



The problem with errors like 413 is that in clients like Subversion we can only 
handle them by showing them as fatal error to the user. The printer scenario 
for upgrades to TLS probably does the same thing. Printing works or doesn’t 
work… It doesn’t allow retrying with a different request.

Not upgrading is an option… But upgrading under less favorable conditions is 
what makes things work.

      Bert

Sent from Mail for Windows 10



From: Yann Ylavic
Sent: zaterdag 12 december 2015 01:46
To: Bert Huijben
Subject: Re: Upgrade Summary


On Sat, Dec 12, 2015 at 12:48 AM, Bert Huijben <b...@qqmail.nl> wrote:
> If you request an upgrade to TLS on your initial request, upgrading with a
> body might still make sense. Especially if the server would respond with a
> 401. But also if the request can be public, but the response needs to be
> secured.

Why using Upgrade at the first place if you are confident enough (to
play auth) with the server being TLS ready?
Wouldn't a direct https connection be better?

Is there such an authentication protocol?
If so, I guess we can do the TLS Upgrade+handshake in the output
filter (as proposed) like any other Protocols Upgrade, letting httpd
handle that first clear text request body...
That's possible without setting aside the body anyway, still I doubt
there is a real need for it (if a TLS Upgrade is asked, the client
shouldn't mind the first (half) round trip and play it's auth on the
second (TLSed) request.

>
> If we blindly ignore the upgrade as ‘doesn’t make sense’, the next request
> wouldn’t use encryption… but if we upgraded to TLS after the request, the
> next request… with the authentication headers could be sent encrypted.

My preference would be to return an error (413), so that the client
notices what's "better" for a TLS Upgrade (no body), but if there
really exist such a cleartext body use case I'm fine with honoring the
body too.

>
> If upgrading the first request doesn’t make sense the client should use a
> different request (Like options *, or HEAD /).

That are, AFAICT, the only use cases so far.

>
> If the server denies the request at least some parts have already travelled
> the network unencrypted. Returning an error or not upgrading will only make
> sure more requests will travel unencrypted.

The client would not send encrypted vs unencrypted (Upgrade) request
depending on the response status, it must send plaintext request
anyway, it ought to know that.
IOW the error response is not a security issue at all, on the contrary
if a client relies on current httpd behaviour to do the handshake
before reading the body, and hence sends private things in the body of
the Upgrade request, it would notice with a response error.
Anyway if the RFC is respected, the TLS handshake doesn't happen
before any body is (fully) received on the server, hence such client
would wait for the handshake before sending anything, and that would
timeout.
Again, an error response is better here...

>
> The response is not the only thing encrypted when upgrading… all future
> requests are. Upgrade is a connection level request, sent via a request.

Agreed.

Regards,
Yann.


Reply via email to