By distributing its requests across the many authoritative servers for the domains you visit. The only one that still sees all your DNS requests is the ISP.
> They see all of your traffic anyway, so it doesn't really matter if they also see your DNS traffic, it's not like HTTPS hides who you are visiting.
Given a lot of traffic goes to cloud providers with IP pools that are discriminated largely by the HTTP Host header, it absolutely does somewhat hide "who you are visiting".
In other words, virtual hosting does provide some incidental "privacy". However, looking at the web as whole, not simply focusing on certain large CDNs, most HTTPS websites actually do not require the SNI extension. "Modern" browsers send domain names in the ClientHello plaintext automatically, by default, even though it is not required.
Then there are HTTPS websites who require SNI but do not actually check the name in ClientHello is the same as the name in the Host header.^1 Any name sent in the ClientHello will suffice to retrieve the correct web page. "Modern" browsers again blindly send more than what is required in that situation.
As such, it is the HTTP client, e.g. major browser, that is leaking information in plaintext unecessarily. "Modern" browsers are useful for displaying web content. However when it comes to retrieving it, they are less trustworthy. Too much is happening in these programs outside the user's awareness and control.
1. AWS Cloudfront is one example. It is possible to send a less descriptive, arguably more private, CNAME in the ClientHello whilst sending the known domain name in the Host header. https://news.ycombinator.com/item?id=21977961
It's sent un-encrypted in the very first handshake setup so the server knows which public key to return. Details here[0].
There is, as you can see from Wikipedia[0], an encrypted version(esni), but that only sort of solves the problem. See [1] for more details on those.
The high level overview is, perfect secrecy of who you are talking to is a very hard problem on the Internet, and while some of these new features might help, there are a LOT of leaks to plug, so if someone is able to watch your traffic go by, chances are they can tell who you are talking to, but they maybe can't figure out what you are saying. Which may or may not matter, depending on your security threat(s).
> is it the certificate handshake where host header is leaked?
Yes, because of SNI [0].
In short, the ClientHello message sent by your browser as the first step of TLS negotiation (After the TCP connection is made, obviously) includes the hostname of the server you are trying to connect to unencrypted so that the server knows which certificate to present in the case of multiple sites being served on one IP/port combo.
No. The SNI is transmitted in plain text as part of the ClientHello but TLS does not care about application implementation details. The HTTP Host header is encrypted along with the rest of the request.