-
Notifications
You must be signed in to change notification settings - Fork 30.2k
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
http_client: prevent domain fronting (Host mismatch) when using proxy #36805
Conversation
Seems the
|
Adjust the implementation to reuse the original IPv6 check. |
…totypeTest Co-authored-by: Antoine du Hamel <[email protected]>
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
Host
in the header field should be changed as thedestination (actual) host
instead of using theproxy (original) host
unless 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).host
to 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/[email protected]
→microsoft/typed-rest-client/[email protected]
→microsoft/typed-rest-client/HttpClient (tunnelAgent)
→request/tunnel-agent#32
koichik/[email protected]
.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-agent
andkoichik/node-tunnel
but MUCH more widely.Compare to the
curl
andrequests
Since 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
host
and original target in thepath
).However, unlike the
curl
andrequests
(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_client
or 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_client
with proxy are shown below respectively.# shell script curl -v http://www.google.com -x http://XXX.XXX.XXX.XXX