httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Bert Huijben <b...@qqmail.nl>
Subject RE: Upgrade Summary
Date Sat, 12 Dec 2015 02:03:49 GMT
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 <bert@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.



Mime
View raw message