Subject: Re: http/1 opportunistic encryption

From: Erik Nygren <[email-masked]>
Date: Fri, 10 Jul 2015 00:41:04 -0400

Out of curiosity, how have current demuxer implementations been handling
and passing the :scheme along?  It may be that many implementations
are ending up in the same situation as http/1.1 here...

For example, how many:

1) Pass :scheme along in a proxyline or similar (eg, OOB channel), with
downstream app handling it properly
2) Pass :scheme along as a "Scheme" request header  (but in a way that is
spoofable and indistinguishable from a client request header)
3) Pass :scheme along as a ":scheme" request header (or some other invalid
HTTP/1.1 header)
4) Fail if :scheme is not "https"
5) Pass :scheme along in a proxyline or similar (eg, OOB channel), with
downstream app ignoring it
6) Drop :scheme entirely

Unfortunately, of these only #1 is actually safe.

As sad as it makes me (due to making interception easier),
I keep coming back to wondering if a separate alpn token would
be safer for h/2 oppsec.

       Erik

On Thu, Jun 18, 2015 at 1:06 PM, Martin Thomson <[email-masked]>
wrote:

> On 18 June 2015 at 01:26, Stefan Eissing <[email-masked]>
> wrote:
> > I think, as a consequence, I need to disable the Alt-Svc support for
> http: in mod_h2, since scheme information is not available to others living
> inside Apache httpd and the described http/1.1 exploit will work exactly
> the same with h2 involved.
>
> It depends on how Apache reports things as being "https" or not.  If
> you can avoid generating those signals or suppress them, then it
> should be OK.
>
> We can certainly improve the text.  Here's what I have:
>
> Some HTTP/1.1 implementations use ambient signals to determine if a
> request is for an `https`
> resource.  For example, implementations might look for TLS on the
> stack or a port number of 443.
> An implementation that supports opportunistically secured requests
> SHOULD suppress these signals if
> there is any potential for confusion.
>
>

---

From: Erik Nygren <[email-masked]>
Date: Fri, 10 Jul 2015 00:45:50 -0400

Actually, #4 is also safe, you just don't get to do it and oppsec together.

---

From: Amos Jeffries <[email-masked]>
Date: Fri, 10 Jul 2015 22:44:09 +1200

> are ending up in the same situation as http/1.1 here...

Why would it be a problem for demuxers?

* HTTP is stateless.
* Messages are self-descriptive.
* Annd RFC 7540 section 8.1.2.3 says:
"
All HTTP/2 requests MUST include exactly one valid value for the
:method, :scheme, and :path pseudo-header fields
"
... with :authority being mandatory except in certain edge cases where
there is no domain:port applicable to the message.

Thus HTTP/2 messages contain all parts of an absolute-URI in their
pseudo-headers. There is intentionally zero ambiguity now about what the
message means. Gone is the HTTP/1 scheme == transport protocol type linkage.

Amos

---

From: Erik Nygren <[email-masked]>
Date: Fri, 10 Jul 2015 10:15:08 -0400

As also discussed in the thread on passing IP addresses, a common
implementation pattern seems to be to bolt an HTTP/2 demuxer in front of an
HTTP/1.x server, sometimes with them communicating such that the HTTP/1.x
server isn't seeing the HTTP/2 communications internals.  What I was
wondering is how people implementing this way pass along the URI elements.
:method, :path, and :authority have clear things to translate into, but
:scheme does not.  Not handling this properly is likely an implementation
bug, but I suspect it will be a common bug.

         Erik

---

From: Amos Jeffries <[email-masked]>
Date: Mon, 13 Jul 2015 22:07:01 +1200

> bug, but I suspect it will be a common bug.

If teh server is compliant with HTTP/1.1 it is expected to accept
absolute-URI not just relative-URI.

My understanding was that :scheme was supposed to be translated into
absolute-URI for the HTTP/1 server when the scheme does not match the
transport protocol used to the server. If it does match then
relative-URI was the right thing to do.

Whether reality matches that spec behaviour though is a good question.

Amos

---

From: Ilari Liusvaara <[email-masked]>
Date: Mon, 13 Jul 2015 13:27:37 +0300

> Whether reality matches that spec behaviour though is a good question.

Well, I have seen a server that when contacted over port 443 and then
queried for http://example.org/ (using absolute-URI form) would
interpret it as query for https://example.org/, and return different
data from intended (expected site front page, got some test page with
200 status).

It was running Apache with PHP (yuck) using FastCGI.

-Ilari

---

From: Mike Bishop <[email-masked]>
Date: Tue, 14 Jul 2015 16:37:09 +0000

IIS/http.sys does this as well.  While requests in absolute form are supported, in the event that two different apps have registered listeners for the http://example.com:80/path and https://example.com:443/path resources, a connection on port 443 requesting http://example.com/path gets routed to the second application.  That hasn't changed in our HTTP/2 implementation.

Frankly, my inclination would be to 503 instead -- *neither* app has registered to serve http://example.com/path over port 443. But that's the legacy we have....

-----Original Message-----
From: Ilari Liusvaara [mailto:[email-masked]] 
Sent: Monday, July 13, 2015 3:28 AM
To: Amos Jeffries
Cc: Erik Nygren; [email-masked] Group
Subject: Re: http/1 opportunistic encryption

> Whether reality matches that spec behaviour though is a good question.

Well, I have seen a server that when contacted over port 443 and then queried for http://example.org/ (using absolute-URI form) would interpret it as query for https://example.org/, and return different data from intended (expected site front page, got some test page with
200 status).

-Ilari

---

From: Erik Nygren <[email-masked]>
Date: Mon, 20 Jul 2015 10:06:56 +0200

This is helpful.  Since it sounds like both IIS/http.sys and Apache have
http/2
implementations that effectively ignore :scheme by default and return
https-scheme
content when receiving :scheme=http over h2+TLS, I wouldn't be surprised
if many other implementations ended up in the same boat.  I'm aware of one
other implementation that started off doing this as well.
If implementations continue to do this, OE becomes just as problematic/risky
over h2 as it is over http1.  Some options (perhaps in decreasing
desirability?) seem to be:

1) Treat ignoring :scheme as a bug --- implementations should return (421
or?) in this case.
    Get implementations fixed and have this a recommended part of server
interop tests
    and list as a common implementation bug.

2) Only do OE over a new TLS ALPN identifier.  This has its own risks and
defeats
     some of the purpose of OE.  On the other hand, it allows for actual
explicit negotiation
     that the client/server supports OE which has other desirable
properties.

3) Give up on worrying about http and https URIs being different and having
different content.
     This would let us do OE over http/1.1 as well  (perhaps just add a
"Scheme:" header under h1).
     There may be some attacks this opens up, and its pedantically
incorrect.

On Tue, Jul 14, 2015 at 6:37 PM, Mike Bishop <[email-masked]>
wrote:

> IIS/http.sys does this as well.  While requests in absolute form are
> supported, in the event that two different apps have registered listeners
> for the http://example.com:80/path and https://example.com:443/path
> resources, a connection on port 443 requesting http://example.com/path
> gets routed to the second application.  That hasn't changed in our HTTP/2
> implementation.
>
> Frankly, my inclination would be to 503 instead -- *neither* app has
> registered to serve http://example.com/path over port 443. But that's the
> legacy we have....
>
> queried for http://example.org/ (using absolute-URI form) would interpret
> it as query for https://example.org/, and return different data from
> intended (expected site front page, got some test page with
> 200 status).
>

---

From: Patrick McManus <[email-masked]>
Date: Mon, 20 Jul 2015 10:31:00 +0200

>     and list as a common implementation bug.

+1 its a bug - let's not bake it in to the Internet. These are early days.

---

From: Stefan Eissing <[email-masked]>
Date: Mon, 20 Jul 2015 10:35:34 +0200

> Am 20.07.2015 um 10:06 schrieb Erik Nygren <[email-masked]>:
> 
> This is helpful.  Since it sounds like both IIS/http.sys and Apache have http/2
> implementations that effectively ignore :scheme by default and return https-scheme

Well, as the one implementing http/2 in Apache, let me say that we do not "end" in
this boat. We "start" in this boat because requirements and concepts of OE are new
in http server configs. If existing servers treat port <=> scheme that seems
a reasonable assumption *pre* OE.

> over h2 as it is over http1.  Some options (perhaps in decreasing desirability?) seem to be:

Exactly the point I tried to raise here. Just waving the "h2" card for the code handling
the ALPN callbacks will not make backend php application well behaved automatically.

> 1) Treat ignoring :scheme as a bug --- implementations should return (421 or?) in this case.
>     Get implementations fixed and have this a recommended part of server interop tests

I think this will not fly. Web servers do not control the applications they are running. For
Apache to guarantee a well-behaved end-to-end OE implementation, it would need an "opt-in" 
by the app processing the request. The best we could do would be to make the default "off"
and let the server admin decide to where and when to turn it on. But he has that option
already when she configures the Alt-Svc.

> 2) Only do OE over a new TLS ALPN identifier.  This has its own risks and defeats
>      some of the purpose of OE.  On the other hand, it allows for actual explicit negotiation
>      that the client/server supports OE which has other desirable properties.

Not helpful, IMHO.

> 3) Give up on worrying about http and https URIs being different and having different content.
>      This would let us do OE over http/1.1 as well  (perhaps just add a "Scheme:" header under h1).
>      There may be some attacks this opens up, and its pedantically incorrect.

I think it would be good for http: to be just the name for a variety of transports that are
negotiated between clients and servers and each transport gives either the very same resource
or is restricted to a only a subset, handing out 403 or 30x on unsuitable ones.

At least that would be my advise for anyone wanting to enable OE on his site - to not, now or
in the future, serve different resources based on scheme. And if they do, they should not
enable OE.

//Stefan

> On Tue, Jul 14, 2015 at 6:37 PM, Mike Bishop <[email-masked]> wrote:

<green/>bytes GmbH
Hafenweg 16, 48155 Münster, Germany
Phone: +49 251 2807760. Amtsgericht Münster: HRB5782

---

From: Mike Bishop <[email-masked]>
Date: Mon, 20 Jul 2015 08:49:30 +0000

The canonical "serve different content" scenario is that http://example.com/path will serve redirects to https://example.com/path rather than actually returning the resource at /path....

-----Original Message-----
From: Stefan Eissing [mailto:[email-masked]] 
Sent: Monday, July 20, 2015 10:36 AM
To: Erik Nygren <[email-masked]>
Cc: Mike Bishop <[email-masked]>; Ilari Liusvaara <[email-masked]>; Amos Jeffries <[email-masked]>; [email-masked] Group <[email-masked]>
Subject: Re: http/1 opportunistic encryption

> This is helpful.  Since it sounds like both IIS/http.sys and Apache 
> have http/2 implementations that effectively ignore :scheme by default 
> and return https-scheme content when receiving :scheme=http over 
> h2+TLS, I wouldn't be surprised if many other implementations ended up 
> in the same boat.  I'm aware of one other implementation that started off doing this as well.

Well, as the one implementing http/2 in Apache, let me say that we do not "end" in this boat. We "start" in this boat because requirements and concepts of OE are new in http server configs. If existing servers treat port <=> scheme that seems a reasonable assumption *pre* OE.

> If implementations continue to do this, OE becomes just as 
> problematic/risky over h2 as it is over http1.  Some options (perhaps in decreasing desirability?) seem to be:

Exactly the point I tried to raise here. Just waving the "h2" card for the code handling the ALPN callbacks will not make backend php application well behaved automatically.

>     and list as a common implementation bug.

I think this will not fly. Web servers do not control the applications they are running. For Apache to guarantee a well-behaved end-to-end OE implementation, it would need an "opt-in" 
by the app processing the request. The best we could do would be to make the default "off"
and let the server admin decide to where and when to turn it on. But he has that option already when she configures the Alt-Svc.

Not helpful, IMHO.

>      There may be some attacks this opens up, and its pedantically incorrect.

I think it would be good for http: to be just the name for a variety of transports that are negotiated between clients and servers and each transport gives either the very same resource or is restricted to a only a subset, handing out 403 or 30x on unsuitable ones.

At least that would be my advise for anyone wanting to enable OE on his site - to not, now or in the future, serve different resources based on scheme. And if they do, they should not enable OE.

//Stefan

> > absolute-URI for the HTTP/1 server when the scheme does not match 
> > the transport protocol used to the server. If it does match then 

<green/>bytes GmbH

---

From: Stefan Eissing <[email-masked]>
Date: Mon, 20 Jul 2015 10:52:53 +0200

> Am 20.07.2015 um 10:49 schrieb Mike Bishop <[email-masked]>:
> 

Sure, 3xx and 4xx may happen for various reasons. 2xx responses should be scheme-invariant, ideally.

<green/>bytes GmbH

---

From: Amos Jeffries <[email-masked]>
Date: Mon, 20 Jul 2015 21:27:37 +1200

On 20/07/2015 8:35 p.m., Stefan Eissing wrote:
> 
>> Am 20.07.2015 um 10:06 schrieb Erik Nygren:
>>

The algorthm in RFC 7230 section 5.5 explicitly starts off with the clause:
"
   If the request-target is in absolute-form, the effective request URI
   is the same as the request-target.
"

The association of port<=>scheme is only placed later in the algorithm,
with clear guideline on what details have to be missing for it to be
assumed.

For consistency, if nothing else, the same algorithm should be used for
HTTP/2 message interpretation. Only...

In HTTP/2 the :scheme pseudo-header and others needed to form
absolute-URI are mandatory. Which makes it always have a well-formed
request-target. That was intentionally done to avoid exactly this bug
from occuring. It saddens me greatly to hear that servers are ignoring
it already on grounds of that being how they treat HTTP/1.

Amos

---

From: Stefan Eissing <[email-masked]>
Date: Mon, 20 Jul 2015 11:51:26 +0200

> Am 20.07.2015 um 11:27 schrieb Amos Jeffries <[email-masked]>:
> 

It's not that bad. Apache is parsing absolute uris and giving them
preference over any host header. But, if I read the code correctly,
it is not prepared to treat a http: scheme correctly when received
over a TLS port.

//Stefan

<green/>bytes GmbH