From c81089642b946fe245c24fb22bdaa653ec943834 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Mon, 11 Mar 2013 17:28:51 -0600 Subject: [PATCH] Fix SSL Bump bypass for intercepted traffic The SSL-bump bypass code on intercepted HTTPS traffic generates a fake CONNECT request from the original destination IP:port in an attempt to trigger a TCP tunnel being opened for the un-bumped data to be transferred over. The current implementation breaks in two situations: 1) when IPv6 traffic is intercepted The URL field generated does not account for the additional [] requirements involved when IPv6+port are combined. The resulting fake requests look like: CONNECT ::1:443 HTTP/1.1 Host: ::1 ... which are both invalid, and will fail to parse. Breaking IPv6 HTTPS interception bypass. Resolve this by using Ip::Address::ToURL() function which was created for the purpose of generating URL hostnames from raw-IP + port with the bracketing inserted when required. 2) when a non-443 port is being intercepted The Host: header generated is missing the port and Squid Host: header validity will reject the outbound CONNECT 127.0.0.1:8443 HTTP/1.1 Host: 127.0.0.1 ... this is an invalid request. Squid is currently ignoring the Host header. However Squid tunnel.cc does make use of peering and may relay the fake request Host: to upstream peers where we cannot be so sure what will happen. Resolve this issue by re-using the generated IP:port string for both URL and Host: fields, which preserves teh port in Host: regardless of value. This also means there is an unnecessary :443 tagged on for most HTTPS traffic, however the omission of port from the Host: header is only a MAY and this should not cause any issues. --- src/client_side.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client_side.cc b/src/client_side.cc index af2c1a6ad5..52e369aa11 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -3641,8 +3641,8 @@ httpsSslBumpAccessCheckDone(allow_t answer, void *data) // fake a CONNECT request to force connState to tunnel static char ip[MAX_IPSTRLEN]; static char reqStr[MAX_IPSTRLEN + 80]; - connState->clientConnection->local.NtoA(ip, sizeof(ip)); - snprintf(reqStr, sizeof(reqStr), "CONNECT %s:%d HTTP/1.1\r\nHost: %s\r\n\r\n", ip, connState->clientConnection->local.GetPort(), ip); + connState->clientConnection->local.ToURL(ip, sizeof(ip)); + snprintf(reqStr, sizeof(reqStr), "CONNECT %s HTTP/1.1\r\nHost: %s\r\n\r\n", ip, ip); bool ret = connState->handleReadData(reqStr, strlen(reqStr)); if (ret) ret = connState->clientParseRequests(); -- 2.47.2