Subject: Talking HTTPS to proxies

From: Willy Tarreau <[email-masked]>
Date: Thu, 14 Apr 2011 21:04:40 +0200

Hello,

I'm regularly encountering what I would call dirty and unreliable
hacks to provide proxy authentication in enterprises. And with the
rise of external proxy services, it's going to get even worse.

A common issue is that in many enterprises, a password must never pass
in clear text over the network. So byebye Basic Auth. Digest requires
that a database of cleartext passwords exists, which is most commonly
refused too. Some proxies support NTLM auth in MS environments, but it
is not the case for all of them, and some proxies simply cannot access
such a service from where they're placed.

Due to this, we're commonly seeing cookie-based authentication methods
which rely on redirects and which are not much reliable if we put the
efficiency aside.

The overall principle is approximately the following (I'm saying approx
because I've seen several variants depending on the will to use popups
or forms, and the trade between security and comfort) :

  1) the browser tries to access example.com through the proxy
  2) the proxy wants user to authenticate and redirects it to a host under
     the proxy's responsibility over https.
  3) the browser follows the redirect through the proxy and gets either an
     auth form or a 401
  4) the user enters his credentials and validates. The request still contains
     a query string with all the info about the original URL at example.com
  5) the proxy accepts them, and issues a redirect to a fake host under
     example.com, with the request still encoded in the query string along
     with a token. It also emits a cookie for the authentication host.
  6) the browser follows the redirect and requests the fake host over HTTP
  7) the proxy intercepts the request, returns a redirect to the initial URL
     with a set-cookie header so that as long as the user remains on the same
     site it will present this cookie.
  8) the browser follows that redirect and finally goes to example.com with
     the cookie.
  9) when the user goes to another site, steps 1 and 2 apply, the proxy
     sees the cookie that was delivered at previous step 5 and is able to
     directly jump there.

Overall, those are a lot of redirects, in order to safely authenticate a
user over the network. Due to this, I've seen some setups where the
credentials are assigned to the client's IP only. That way once the user is
authenticated, everybody can access the proxy under his credentials just
by being relayed by his PC. This is a common trick in big enterprises.
Another workaround consists in authenticating the connection regardless
of any request in it. Some clients can then share the same connection by
inserting a proxy in the middle and all browse over the same connection
(I already encountered this case too).

And the cherry at the top of the cake is that this doesn't work well.
Some sites make use of flash which does not send the cookies (so the
proxy vendors use other tricks for that), and when the users's cookie
for the authentication host expires, you see lots of funny things. If
it expires when loading an image, you often never get it and don't see
the auth form either. Also, XHR and POSTs don't work well either : POSTs
to a site not covered by the current cookie will have its contents lost,
and both XHR and POSTs will be lost when the auth cookie expires (very
annoying in webmails where you know that all your mail's contents are
lost when you see the popup after clicking "send"). 

What I've realized is that all those horrors only exist because browsers
offer no provisions for connecting to proxies over HTTPS instead of HTTP.
It would be amazingly simple. We'd just have to check the box "use HTTPS"
in the browser's config, retrieve the proxy's certificate and everything
could safely be exchanged with the proxy. Even basic auth would be easy
to use and safe. We could also make use of client certificates with this.

So what I'm wondering now is why we have not seen this yet. Is it because
nobody has brought the issue yet, because the vendors who implement the
horrors I described above are too happy to be ahead of competition when
it comes to deploying safe authentication methods, because there are
major drawbacks in doing this, or because I'm stupid and have never
found how to enable this ?

I'm sure that some proxies do probably already support it as a side effect
of being used as SSL reverse-proxies. We only need browsers to add the
checkbox in their proxy config to enable this. I have heard about some
sites where an stunnel-like component is installed on the user's PC (either
as a java applet or as a real daemon) and simply transforms the cleartext
HTTP traffic into HTTPS to connect to the proxy. (I did not see those myself,
I only saw applets to use stronger crypto than what the browser offers, but
they were not deployed as explicit proxies).

Shouldn't we try to encourage both browser vendors and proxy vendors to enable
HTTPS ?

Thanks for any insight,
Willy

---

From: William Chan (陈智昌) <[email-masked]>
Date: Thu, 14 Apr 2011 21:37:48 +0200

FWIW, Google Chrome supports HTTPS proxies (
http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/net/proxy/proxy_server.h&l=55
).

---

From: Willy Tarreau <[email-masked]>
Date: Thu, 14 Apr 2011 22:47:09 +0200

Hi William,

> http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/net/proxy/proxy_server.h&l=55

Excellent, thanks for the pointer ! Maybe a few other ones also do ?
If in the end we can find a list of those which don't support them,
we'll be able to contact them and suggest to do so too.

Cheers,
Willy

---

From: Adrien de Croy <[email-masked]>
Date: Fri, 15 Apr 2011 11:17:56 +1200

William

are you sure this isn't just support for SSL tunnelling via the CONNECT 
method?

the Chrome UI (or are you referring to the Chromium open source project) 
uses Internet Explorer settings for proxy config, which doesn't support 
making a TLS connection to the proxy.

WinGate 7 supports TLS proxy connections (and conditional auth methods 
depending on connection security) if anyone needs to test.

Regards

Adrien

On 15/04/2011 7:37 a.m., William Chan (陈智昌) wrote:
> FWIW, Google Chrome supports HTTPS proxies 
> (http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/net/proxy/proxy_server.h&l=55 
> <http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/net/proxy/proxy_server.h&l=55>).
>
> On Thu, Apr 14, 2011 at 9:04 PM, Willy Tarreau <[email-masked] 
> <mailto:[email-masked]>> wrote:
>
>     Hello,
>
>      1) the browser tries to access example.com <http://example.com>
>     through the proxy
>         a query string with all the info about the original URL at
>     example.com <http://example.com>
>     example.com <http://example.com>, with the request still encoded
>     in the query string along
>      8) the browser follows that redirect and finally goes to
>     example.com <http://example.com> with
>         the cookie.

-- 
Adrien de Croy - WinGate Proxy Server - http://www.wingate.com

---

From: William Chan (陈智昌) <[email-masked]>
Date: Fri, 15 Apr 2011 01:30:26 +0200

> are you sure this isn't just support for SSL tunnelling via the CONNECT

Yes, I'm sure. I reviewed most of the code for this feature. It's
experimental right now.

> making a TLS connection to the proxy.

Correct. We haven't changed the UI to support this. You can configure it via
command line flag though.

>> example.com
>>  8) the browser follows that redirect and finally goes to example.comwith
>>     the cookie.

---

From: Adrien de Croy <[email-masked]>
Date: Fri, 15 Apr 2011 11:47:08 +1200

Hi

I think it's a good idea, but there could be some gotchas, especially 
with proxies that intercept SSL connections on port 443 and do MITM so 
they can scan https traffic.

In fact scanning https traffic is a big problem for companies, since 
more malware uses https to download more malware to avoid scanning.

I'm wondering if it wouldn't be a good time to start getting browsers to 
off-load the actual TLS function to the proxy.

e.g. if a browser is using a proxy, and wants to go to 
https://secure.qbik.com, currently they do

CONNECT secure.qbik.com:443 HTTP/1.1
etc

then (maybe) negotiate their own SSL/TLS connection, then send (maybe) 
an HTTP request.  I say maybe, because in many cases, the client can do 
whatever they like with the connection.

If instead the client sent

GET https://secure.qbik.com HTTP/1.1
etc

then several benefits come about:

a) the proxy knows (and can enforce) that the client is using http over 
SSL/TLS.  In fact the proxy implements it.
b) the proxy doesn't need to use dest port in policy for CONNECT, since 
CONNECT can be blocked off completely, and https://site:port syntax can 
be used instead.
c) the proxy can do cert validation for the client
d) the proxy can scan the data, cache it etc.

It would be trivially simple for a proxy to support https:// syntax, as 
well as a client to use it.  It would need to become an optional setting 
in the client though, whether to use a tunnel, or https:// request 
semantics.

tunneling is a security quagmire, it would be great to be able to lock 
it down.  At the moment, there aren't many options, since the proxy only 
sees server:port.  CONNECT is abused by many applications.

Adrien

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 15 Apr 2011 06:43:26 +0200

Hi Adrien,

> off-load the actual TLS function to the proxy.

Agreed. Anyway, in many cases, the proxies have to do other tricks such
as presenting fake certificates to browsers in order to be able to scan
HTTPS traffic, so where this is deployed, the proxy is already the one
terminating the SSL for both sides, except the client is not aware of it
at all.

> in the client though, whether to use a tunnel, or https:// request 

I agree with your proposal, and in fact once the SSL/TLS tunnel is possible
between the client and the proxy, it seems really obvious that it should
work like this ! The client would then be aware of the offloading. It could
even be possible for the proxy to inform the client via a header that the
server's cert had issues (eg: expired, etc...) and the company's security
policy could decide whether the proxy accepts such connections and reports
the issue or blocks them.

> sees server:port.  CONNECT is abused by many applications.

I'm well aware of that, I'm abusing it on a daily basis to access my mail
over SSH, which is made possible via all the horrors I described in the
first mail :-)

Regards,
Willy

---

From: Mike Belshe <[email-masked]>
Date: Fri, 15 Apr 2011 19:58:12 -0700

Willy -

I love you idea.  I think all browser vendors should support TLS to the
proxy itself.

We ran into the *exact* cookie redirect problem that you ran into.

On Thu, Apr 14, 2011 at 4:30 PM, William Chan (陈智昌)
<[email-masked]>wrote:

> Correct. We haven't changed the UI to support this. You can configure it
> via command line flag though.
>

As a horrible testing hack, you can also use the proxy PAC file - use "HTTPS
<proxyname>" instead of "PROXY <proxyname>".

Keep in mind the wpad.dat fetching is completely unsecured....  But for
testing this works great.   You can even do SPDY this way (ah, true
motivations are revealed!)

Mike