When a browser needs to send a HTTPS request through a proxy (like Fiddler), there’s a bit of a problem.
The proxy needs to know where to send the client’s request, but the whole point of protecting traffic with HTTPS is that the content is encrypted and cannot be read by anyone else on the network, including the proxy!
To resolve this Catch-22, a trick is used– the browser sends a HTTP request with the method CONNECT and the target hostname and port to which the client would like a connection:
CONNECT bayden.com:443 HTTP/1.1
Upon receiving such a request, the proxy is expected to establish a TCP/IP connection to the requested hostname and port and signal its success by returning a HTTP/200 response indicating that the requested connection was made:
HTTP/1.1 200 Connection Established
Subsequently, the proxy is expected to just blindly shuffle all bytes back and forth between the client and the server connections without looking at them. The client and server perform their HTTPS handshakes and then exchange encrypted traffic (typically, one or more HTTPS requests and responses). When the connection is no longer needed, either side closes the connection and the proxy, upon receiving notice that one side has closed the connection, closes the other side of the connection too.
We often refer to connections established in this way Proxy Tunnels.
In Fiddler, tunnels are represented by a grey lock icon with the text “Tunnel to” in place of the Host field; the URL field shows the target hostname and port, as seen in the first line of the screenshot:
Notably, Fiddler isn’t limited to blind proxy tunnels, it can execute a man-in-the-middle against both sides of the connection, pretending to the client that it is the server and pretending to the server that it is the client. When you enable HTTPS decryption in Fiddler, the proxy tunnel in the Web Sessions list is followed by all of the requests and responses that were transferred through that tunnel (as shown in the second and third lines in the screenshot).