Subject: Sec-Scheme request header?

From: Mark Nottingham <[email-masked]>
Date: Wed, 13 Apr 2016 17:50:48 +1000

At the WG meeting in B-A, I tangentially wondered aloud about whether we should define a header in the form:

Sec-Scheme: https

Because it's prefixed with `Sec-`, browsers won't allow its modification (e.g., in XHR), so its value is relatively trustworthy from browser clients.

Because it's a header, rather than a pseudo-header (like :scheme), it's "end to end" -- it gets exposed to the application (e.g., through PHP, CGI, whatever) via standard APIs. As such, it's much more realistic to consume.

What do people think -- would such a thing be useful? 

--
Mark Nottingham   https://www.mnot.net/

---

From: Mike West <[email-masked]>
Date: Wed, 13 Apr 2016 09:54:36 +0200

On Wed, Apr 13, 2016 at 9:50 AM, Mark Nottingham <[email-masked]> wrote:

> Because it's prefixed with `Sec-`, browsers won't allow its modification
> (e.g., in XHR), so its value is relatively trustworthy from browser clients.
>
> Because it's a header, rather than a pseudo-header (like :scheme), it's
> "end to end" -- it gets exposed to the application (e.g., through PHP, CGI,
> whatever) via standard APIs. As such, it's much more realistic to consume.
>

Could you explain the use-case? Ctrl+F in
https://github.com/httpwg/wg-materials/blob/gh-pages/ietf95/minutes.md came
up empty, so context would be helpful. :)

-mike

---

From: Patrick McManus <[email-masked]>
Date: Wed, 13 Apr 2016 09:41:19 -0400

> up empty, so context would be helpful. :)

I think we were discussing the general milieu of request routing complexity
(421, coalescing, alt-svc, etc..).. and how the scheme was the one part of
the origin that isn't always available to the final consumer of the request
whether that is because it is h1 and not in the request at all, or whether
it is because in h2 it is carried in a transport level colon header..

---

From: Martin Thomson <[email-masked]>
Date: Wed, 13 Apr 2016 10:53:16 -0300

> it is because in h2 it is carried in a transport level colon header..

Mark suggested that all existing places that carry a scheme might end
up being eroded, by virtue of them being known to intermediaries and
stacks and the like.  For example, most server software gently
converts absolute URIs into a bare path (sometimes ignoring the
authority part, IIRC).

The Sec-Scheme idea was a way of getting an unequivocal signal from
the client to the code serving a resource without all that mess
getting in the way.

Why this wouldn't also be eroded in the same way is down to freshness.
Next time, we'll try Sec-NoIMeanIt-Scheme. </snark>

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 14 Apr 2016 10:15:13 +1000

> Next time, we'll try Sec-NoIMeanIt-Scheme. </snark>

Nope.

The motivation here is that there is no standard way to determine the client's idea of what the scheme is at the server in HTTP/1.x, and while we define :scheme in H2, we short-sightedly made it a pseudo-header, meaning that there's no standard way for it to be exposed to server-side code.

This is especially evident in situations like those that Julian described, where a request might go through infrastructure like this:

--> CDN --> Reverse Proxy --> Origin Server --> PHP runtime --> PHP framework --> Application code

... and :scheme information might be stripped at any of these stages. 

Right now, different servers, runtimes and frameworks have different ways of determining the context of the connection (using port numbers, static configuration, presence of TLS, etc.), leading to confusion and resulting potential for security problems.

Having a clear signal about the scheme in use from the client that "punches through" all of this in a way that's easy for the frameworks and application code to access and reason about *seems* like it would be a useful thing for them. 

Cheers,

---

From: Mike West <[email-masked]>
Date: Thu, 14 Apr 2016 09:52:24 +0200

On Thu, Apr 14, 2016 at 2:15 AM, Mark Nottingham <[email-masked]> wrote:

> The motivation here is that there is no standard way to determine the
> client's idea of what the scheme is at the server in HTTP/1.x, and while we
> define :scheme in H2, we short-sightedly made it a pseudo-header, meaning
> that there's no standard way for it to be exposed to server-side code.
>
> This is especially evident in situations like those that Julian described,
> where a request might go through infrastructure like this:
>
> Right now, different servers, runtimes and frameworks have different ways
> of determining the context of the connection (using port numbers, static
> configuration, presence of TLS, etc.), leading to confusion and resulting
> potential for security problems.
>
> Having a clear signal about the scheme in use from the client that
> "punches through" all of this in a way that's easy for the frameworks and
> application code to access and reason about *seems* like it would be a
> useful thing for them.
>

What kind of reasoning do you expect this header to enable?

I'm a little worried about terminating TLS somewhere, but carrying a
"totally secure" indicator through various proxies and etc. until reaching
an origin server. Doesn't that seem more confusing and problematic than
status quo? "SSL added and removed here", and etc.

-mike

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 14 Apr 2016 18:00:53 +1000

> On 14 Apr 2016, at 5:52 PM, Mike West <[email-masked]> wrote:
> 
> I'm a little worried about terminating TLS somewhere, but carrying a "totally secure" indicator through various proxies and etc. until reaching an origin server. Doesn't that seem more confusing and problematic than status quo? "SSL added and removed here", and etc.

It's not a totally secure indicator; it's an indicator of what state the client is in WRT scheme. That state isn't explicit now, so server-side software has to guess.

This is something that would be really useful for disambiguating things in cases where the same server-side code is handling both HTTP and HTTPS URLs. 

The Opportunistic Security draft was one place this came up; I'm wondering if it'd be useful in other ways.

To be clear, I'm not pushing this, just wondering out loud.

Cheers,

---

From: Mike West <[email-masked]>
Date: Thu, 14 Apr 2016 10:06:43 +0200

On Thu, Apr 14, 2016 at 10:00 AM, Mark Nottingham <[email-masked]> wrote:

> This is something that would be really useful for disambiguating things in
> cases where the same server-side code is handling both HTTP and HTTPS URLs.
>

I think I'd prefer to encourage folks to treat HTTP and HTTPS as "the same"
with regard to the resource which is being universally {identified,
located}. I freely admit, however, that I'm not at all familiar with what
developers do with backend servers and proxies and CDNs, so I'm sure there
are solid use cases I'm missing. Could you point me to some?

-mike

---

From: Amos Jeffries <[email-masked]>
Date: Thu, 14 Apr 2016 22:25:09 +1200

On 14/04/2016 8:06 p.m., Mike West wrote:
> On Thu, Apr 14, 2016 at 10:00 AM, Mark Nottingham wrote:
> 

Taking the abstract view we have several cases:

1) anything talking to legacy install 1.1 servers
 - nothing helps here. old software ignores new features.
 - when its upgraded the new software will become h2-enabled right?
which makes it move to another case.

2) h2 enabled server/gateway talking to legacy install 1.1 client
 - nothing helps here.
 - thats the clients fault, and when upgraded will become h2-enabled
which is a higher numbered case.

3) h2 client talking to h2 server.
 - just use :scheme. Wins all around.

4) h2 enabled client/server endpoints talking over 1.1 middleware
 - Scheme: might help.

BUT actually using absolute-URL for the request-target would help more.
Since it helps ensure the scheme + host are treated as a pair and not
getting separated or confused.

BUT, lets be honest explicit-proxy middleware is already using
absolute-URL so case #4 is only a problem when interception MITM are
present.

So the radical and politically incorrect proposal:
  begin a campaign to get clients to just use absolute-URL over 1.1
regardless of the connection type. Port 80, port 443, taking to an
explicit proxy - no more special casing just send absolute-URL.

In its favour this campaign can be done with just a consensus and small
amount of conspiracy to actually implement by us WG participants. It
does not require full h2 implementation to participate, and there is a
slight/rare chance it might actually do something useful for case #1.
And it simplifies and should speed up processing in both browsers and
the annoyingly slow MITM middleware.

On the downside we hit an (unkown?) amount of servers not complying with
the RFC requirement to accept absolute-URL. And other weirdness, like
ignoring it in favour of Host (which could be dropped BTW, more savings!).

Amos