saucesteals / utlsproxy

MITM Proxy with TLS mimicry
GNU General Public License v3.0
38 stars 4 forks source link

It breaks when the target website supports HTTP1.1 only #1

Closed HMaker closed 6 months ago

HMaker commented 10 months ago

goproxy fails to properly proxy HTTP 1.1 connections. I guess the issue is that goproxy assumes both the target website and the proxy client use the same HTTP version.

It will break in scenarios like:

[website] <=== HTTP 1.1 ===> [utlsproxy] <=== HTTP 2 ===> [client]

I think the goproxy fork need to read the full HTTP response from the target website before forwarding it to the client, this way HTTP version mismatch can be supported. From what I understood your goproxy fork is forwarding the response at the network byte level: https://github.com/saucesteals/goproxy/blob/a928e14414df60eefb6a9078731c4314f4743347/https.go#L265-L279

The original goproxy seem to handle it properly: https://github.com/elazarl/goproxy/blob/7cc037d33fb57d20c2fa7075adaf0e2d2862da78/https.go#L197-L323

saucesteals commented 10 months ago

The forwarding at the tls layer is intentional and the most straightforward way to avoid letting the server fingerprint the http layer.

You should only ever use this fork when you are having issues with getting fingerprinted while proxying. If the server doesn't even support http2 (in your scenario) there is no reason not to use simpler alternatives like Proxyman and Charles. HTTP1 is very simple and barely has anything you can fingerprint, so if the server does not even support http2 then it's safe to assume they do not care about your fingerprint.

HMaker commented 10 months ago

Yes but in my case the target server is guarded by Cloudflare. Charles is fingerprinted (TLS).

I forked your goproxy and made it always use http 1.1 for the proxy client.

saucesteals commented 10 months ago

You're sure you're getting blocked because of your clienthello? Seems unlikely but possible I guess, weird that the website would explicitly disable http2 on cloudflare but still use their waf...

HMaker commented 10 months ago

Yes I am sure. I am proxying traffic from iOS, the clienthello difference seem to be relevant.

They made CF use HTTP 1.1 probably to match with their backend and avoid HTTP2 <> HTTP1 translation. They always used HTTP 1.1 even before CF be deployed.

HMaker commented 10 months ago

I think utlsproxy should take the http version as a cli argument so people could change it when this version mismatch happens. That version would be used only for the utlsproxy <> client connection.

It would be set at https://github.com/saucesteals/goproxy/blob/a928e14414df60eefb6a9078731c4314f4743347/https.go#L220

It also should log a warning when that mismatch happens and suggest the user to pin the http version using that argument.

saucesteals commented 10 months ago

Agreed, a flag to force http1 is sufficient enough Let me know if #2 works for you

HMaker commented 6 months ago

Yes it should be enough, thanks