Branch: Tag:

2019-09-25

2019-09-25 14:19:14 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Protocols.HTTP: Keep proxy CONNECT and request headers separate.

This makes sure that we do not leak Authorization- and Cookie-
headers to the proxy.

Fixes PIKE-216 (#8216).

171:    proxy = Standards.URI(proxy);    url = Standards.URI(url);    -  mapping(string:string|array(string)) proxy_headers; +  mapping(string:string|array(string)) proxy_headers = ([]);       if( user || password )    { -  if( !request_headers ) -  proxy_headers = ([]); -  else -  proxy_headers = request_headers + ([]); -  +     proxy_headers["Proxy-Authorization"] = "Basic "    + MIME.encode_base64((user || "") + ":" + (password || ""), 1); -  +  }    if (has_value(proxy->host, ":")) {    proxy_headers["host"] = "[" + proxy->host + "]:" + proxy->port;    } else {    proxy_headers["host"] = proxy->host + ":" + proxy->port;    } -  } +        if (url->scheme == "http") {    if( query_variables )
200:    url->port = proxy->port;    query_variables = url->query = 0;    url->path = web_url; +  +  if (request_headers) { +  proxy_headers = request_headers + proxy_headers; +  }   #if constant(SSL.File)    } else if (url->scheme == "https") {   #ifdef HTTP_QUERY_DEBUG
209: Inside #if constant(SSL.File)
   // Make a CONNECT request to the proxy,    // and use keep-alive to stack the real request on top.    proxy->path = url->host + ":" + url->port; -  if (!proxy_headers) proxy_headers = ([]); +     proxy_headers->connection = "keep-alive"; -  m_delete(proxy_headers, "authorization"); // Keep the proxy in the dark. +     con = do_method("CONNECT", proxy, 0, proxy_headers);    con->data(0);    if (con->status >= 300) {
559:    error("Asynchronous httpu or httpmu not yet supported.\n");    }    -  mapping(string:string|array(string)) proxy_headers; +  mapping(string:string|array(string)) proxy_headers = ([]);       if( user || password )    { -  if( !request_headers ) -  proxy_headers = ([]); -  else -  proxy_headers = request_headers + ([]); -  +     proxy_headers["Proxy-Authorization"] = "Basic "    + MIME.encode_base64((user || "") + ":" + (password || ""), 1); -  +  }    if (has_value(proxy->host, ":")) {    proxy_headers["host"] = "[" + proxy->host + "]:" + proxy->port;    } else {    proxy_headers["host"] = proxy->host + ":" + proxy->port;    } -  } +        if (url->scheme == "http") {    if( query_variables )
588:    url->port = proxy->port;    query_variables = url->query = 0;    url->path = web_url; -  if (!proxy_headers) proxy_headers = request_headers; +  +  if (request_headers) { +  proxy_headers = request_headers + proxy_headers; +  }   #if constant(SSL.File)    } else if(url->scheme == "https") {   #ifdef HTTP_QUERY_DEBUG
600: Inside #if constant(SSL.File)
   proxy->path = url->host + ":" + url->port;    if (!proxy_headers) proxy_headers = ([]);    proxy_headers->connection = "keep-alive"; -  m_delete(proxy_headers, "authorization"); // Keep the proxy in the dark. +        array(mixed) orig_cb_info = ({    con->request_ok,
612: Inside #if constant(SSL.File)
   orig_cb_info,    url, method,    query_variables, -  request_headers && request_headers + ([]), +  request_headers,    data);    method = "CONNECT";    url = proxy;