-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
http_client: prevent domain fronting (Host mismatch) when using proxy #36805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Seems the
|
|
Adjust the implementation to reuse the original IPv6 check. |
…totypeTest Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
I'm not sure if weather this PR gets accepted or when will it be landed even got accepted. |
Purpose
This PR is to prevent domain fronting warning/misjudgment (Host mismatch with the one in header) issue when using proxy
Explanation
We are informed by the security team in our company that our http requests contain mismatched Destination Host and Header Host.
According to the tutorial,
a Host header field must be sent in all HTTP/1.1 request messages.That's why Node.js do the
setHeader('Host', hostHeader)with the givenhost(options.hostname/host or localhost) by default.However, the
Hostin the header field should be changed as thedestination (actual) hostinstead of using theproxy (original) hostunless user force overwrite it withoptions.headers['Host'].Implementation
Since
this.path = options.path || '/'set the path as/by default, I decide to check if the path has its own host (i.e., NOT start with a slash) with!this.path.startsWith('/').Next, use the built-in
new URL(path).hostto get the host, while theis used to prevent invalid URL, such ashttp://${this.path.replace(/^.*:\/\//, '')}❌github.com(vs.✔️https://github.com) that raises an exception.Further discussion
Origin
This issue was found when running the Azure DevOps task with API calls.
The sample call stack would like:
microsoft/azure-devops-node-api@8.1.1→microsoft/typed-rest-client/RestClient@1.2.0→microsoft/typed-rest-client/HttpClient (tunnelAgent)→request/tunnel-agent#32koichik/node-tunnel@0.0.4.Actually, the request/tunnel-agent#32 and request/tunnel-agent#40 address this issue (host mismatch instead of domain fronting though) but that library has been out of maintenance since Mar. 2017.
Besides, this issue occurs mainly because the way Node.js generating the default Host header field; therefore, it influences not only the
request/tunnel-agentandkoichik/node-tunnelbut MUCH more widely.Compare to the
curlandrequestsSince Node.js doesn't have a built-in proxy support for HttpClient (or I just missed one ...?), the simplest workaround would be the one mentioned on Stack Overflow (put the proxy in the
hostand original target in thepath).However, unlike the
curlandrequests(Python) that have built-in proxy support, Node.js doesn't handle the Host field in header correctly as expected.I'm not sure if making this change goes against the design concept of the
http_clientor not, but I think it's important to get correct Host in header even though it doesn't matter or even be noticed in most cases.The sample code and the result screenshot for GET requests using
curl,requests, andhttp_clientwith proxy are shown below respectively.# shell script curl -v http://www.google.com -x http://XXX.XXX.XXX.XXX