saucesteals / utlsproxy

MITM Proxy with TLS mimicry

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

It breaks when the target website supports HTTP1.1 only

HMaker opened this issue · comments

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

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.

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.

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...

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.

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.

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

Yes it should be enough, thanks