http_client: prevent domain fronting (Host mismatch) when using proxy#36805
Closed
LouisSung wants to merge 5 commits intonodejs:masterfrom
LouisSung:patch-1
Closed
http_client: prevent domain fronting (Host mismatch) when using proxy#36805LouisSung wants to merge 5 commits intonodejs:masterfrom LouisSung:patch-1
LouisSung wants to merge 5 commits intonodejs:masterfrom
LouisSung:patch-1
Conversation
aduh95
reviewed
Jan 5, 2021
mscdex
reviewed
Jan 6, 2021
Author
|
Seems the
|
Author
|
Adjust the implementation to reuse the original IPv6 check. |
aduh95
reviewed
Jan 13, 2021
LouisSung
commented
Jan 17, 2021
…totypeTest Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com>
Author
I'm not sure if weather this PR gets accepted or when will it be landed even got accepted. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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