lwthiker / curl-impersonate

curl-impersonate: A special build of curl that can impersonate Chrome & Firefox
MIT License
3.65k stars 244 forks source link

Wrong host header using CURL_IMPERSONATE env var #53

Closed momala454 closed 2 years ago

momala454 commented 2 years ago

When using libcurl and reusing the same connection, if I set the "Host:" header on the connection, and reuse it to make a request without the host header, the header is still included with the same value

<?php
putenv('CURL_IMPERSONATE=chrome98');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://headers.cf');
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
curl_setopt( $ch, CURLOPT_ENCODING, "" );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, false );
curl_setopt( $ch, CURLOPT_ENCODING, "" );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, ['Host: abc.com']);
curl_setopt( $ch, CURLOPT_AUTOREFERER, true );

curl_exec($ch);
print_r(curl_getinfo($ch));

//curl_reset($ch);
curl_setopt($ch, CURLOPT_URL, 'https://headers.cf');
curl_setopt( $ch, CURLOPT_HTTPHEADER, ['connection: Keep-Alive']); // i didn't set "host:" there

echo curl_exec($ch);
print_r(curl_getinfo($ch));

ON the first request, this is what is sent

GET / HTTP/1.1
Host: abc.com <--- notice this
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

and this is sent on the second request

GET / HTTP/1.1
Host: abc.com <--- this is incorrect
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
connection: Keep-Alive

if i remove the line putenv('CURL_IMPERSONATE=chrome98');, everything works fine : first request :

GET / HTTP/1.1
Host: abc.com <-- notice this
Accept: */*
Accept-Encoding: deflate, gzip, br

second request

GET / HTTP/1.1
Host: headers.cf <--- this is correct this time
Accept: */*
Accept-Encoding: deflate, gzip, br
connection: Keep-Alive
momala454 commented 2 years ago

even if I set "Host: hello.com" on the second request, it still send "abc.com" as host when i'm using CURL_IMPERSONATE

momala454 commented 2 years ago

hello, did you saw this issue ?

lwthiker commented 2 years ago

Hi, yes I saw it. Thanks for reporting. My time was quite limited the past week so I didn't manage to inspect this yet.

momala454 commented 2 years ago

Ok thanks for your hard work

momala454 commented 2 years ago

hello, could you please look at it, this issue is preventing me to use it. The others issue I mentioned are less important thank you

lwthiker commented 2 years ago

I will prioritize it, I might have some free time next week. Sorry for the delay, busy times...

By the way, I understand the need for reusing the curl handle when connecting to the same host, but what is the purpose if you are connecting to a different one? A new connection is initiated, so why not use a new handle?

momala454 commented 2 years ago

I have a generic http query to do request and sometimes it will be on different host but sometime the same. Thank you

lwthiker commented 2 years ago

@momala454 I think I fixed the issue in #62 . I tested the fix using C code, would you mind testing it with your PHP code as well? Once you give me the green light I would merge it to the main branch.

The issue was quite tricky - you found a real edge case here. Luckily the fix was simple.

foremtehan commented 2 years ago

@momala454 not related to this issue, But can you tell how are you able to use chrome98 as curl handler in PHP ? I dont this using putenv('CURL_IMPERSONATE=chrome98'); is enough right ?

momala454 commented 2 years ago

@foremtehan yes it's enough as soon as you use the libcurl from this library instead of the default one

momala454 commented 2 years ago

@momala454 I think I fixed the issue in #62 . I tested the fix using C code, would you mind testing it with your PHP code as well? Once you give me the green light I would merge it to the main branch.

The issue was quite tricky - you found a real edge case here. Luckily the fix was simple.

thanks for the fix. I've tested and it worked fine. Take note that I tested with both https://github.com/lwthiker/curl-impersonate/pull/62 and https://github.com/lwthiker/curl-impersonate/pull/44 at the same time