Using HTTP Pipelining to hide requests

This is not a security concern for the client.

There is a technique called domain fronting, where a specially configured client creates a TLS connection to www.amazon.com on the HTTPS port – it resolves www.amazon.com, creates a TCP connection to the IP it receives (which will be an Amazon load balancer), send a TLS handshake with a SNI of www.amazon.com, and expects and properly validates the certificate for www.amazon.com.

However, once the connection is established, it does not send a HTTP request for www.amazon.com through that connection. Instead, it sends a HTTP request for something like speciallyconfiguredproxy.example.cloudfront.com (i.e. a HTTP GET or POST request with that host name in the Host header). Cloudfront is Amazon’s reverse proxy service. If it runs on the same load balancers as amazon.com, the load balancer will forward this to a proxy instance that belongs to the entity that developed the specially configured client.

The advantage for this is that to anyone observing the connection, this is virtually indistinguishable from a regular connection to amazon.com. This allows someone to talk to their own server, while anyone observing the connection doesn’t see anything suspicious. This can be used e.g. to bypass censorship, or to hide the command-and-control connection of malware.

Amazon doesn’t like that, probably because there’s a risk that censors will decide the collateral damage tolerable and may block all connections to amazon.com to close the loophole. You can read more in a blog post from the makers of Signal (the private messenger app) which was using this technique for censorship avoidance.

Apparently, Amazon was checking that the Host header matches the value sent in the SNI only for the first request, and this trick bypasses that and lets you use domain fronting despite Amazon trying to prevent it (until they catch you and shut down your account, of course).

Leave a Reply