FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Ensure IPv6 hostname is enclosed within square brackets in Host header by mpotra · Pull Request #5314 · nodejs/node · GitHub

/ node Public

Ensure IPv6 hostname is enclosed within square brackets in Host header - #5314

Closed
mpotra wants to merge 1 commit into
nodejs:masterfrom
mpotra:http-host-header-ipv6
Closed

Ensure IPv6 hostname is enclosed within square brackets in Host header#5314
mpotra wants to merge 1 commit into
nodejs:masterfrom
mpotra:http-host-header-ipv6

Conversation

mpotra commented Feb 18, 2016

Copy link
Copy Markdown
Contributor

Fixes #5308

As per https://tools.ietf.org/html/rfc7230#section-5.4 and https://tools.ietf.org/html/rfc3986#section-3.2.2 IPv6 addresses in Host header (URI), must be enclosed within square brackets, in order to properly separate the host address from any port reference.

mscdex added the http Issues or PRs related to the http subsystem. label Feb 19, 2016

mscdex commented Feb 19, 2016

Copy link
Copy Markdown
Contributor

It looks like the file permissions for _http_client.js were changed?

mpotra commented Feb 19, 2016

Copy link
Copy Markdown
Contributor Author

Thank you for noticing, and I apologize for the mistake. Not sure how that happened, but I'll update the PR with the permissions change reverted.

mpotra force-pushed the http-host-header-ipv6 branch from c3faa8d to 0f7bf56 Compare February 19, 2016 08:30
Comment thread lib/_http_client.js Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Maybe use net.isIPv6(hostHeader) here instead?

Comment thread lib/_http_client.js Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

very minor nit... these can use template strings now.. [${hostHeader}]... not critical tho :-)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Isn't string concatenation faster than template strings?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I want to say that some benchmarks have shown that template strings do not introduce any performance issues, maybe even improve performance. Will have to look and see if I can find them though.

jasnell commented Feb 19, 2016

Copy link
Copy Markdown
Member

LGTM

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

if you wrap this in a common.mustCall(function(req, res) { }), then the hadRequest can be be totally removed. It doesn't look like hadError is used at all, so that can be removed. With those two gone, we can also remove the process.on('exit') listener.

Copy link
Copy Markdown
Contributor

If you can address the nits that both myself and @jasnell have mentioned, LGTM. Once that is done, we can run the CI and make sure everything is passing. Thanks for the contribution!

Comment thread lib/_http_client.js Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

isn't this too heavyweight?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

In my initial PR, IPv6 checking was done by hostHeader.indexOf(':'), just as you also suggested in #5308
However, now I agree that net.isIPv6() is a much more reliable way of testing for IPv6.

I don't necessarily think it's too heavyweight, since it relies on uv_inet_pton. I guess it's slightly slower than indexOf, but since it also checks for valid characters inside the string, I believe it's worth the extra cycles.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

There were no check for correctness here before, so I assume that there are two possibilities:

  1. Host is check before and is valid at this point, so if there is : then it can only possibly be IPv6 address.
  2. Host isn't checked before, so it might be invalid. If it has : then it is either IPv6 or invalid. If we wrap invalid host in brackets it would still be invalid, so it doesn't really matter.

isIPv6 involves calling C++ code and also checking if argument is IPv4 before checking if it's IPv6.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Host value doesn't pass through proper validation. It actually relies on either url.parse() to produce a host value, or simply takes options.hostname || options.host. At this stage, especially if options object is passed to the request(), hostHeader could even be www.domain.tld:3000, before reaching my code; (which is not wrong, only unsupported atm). In this case, a simple : check would yield an invalid Host header [www.domain.tld:3000].

Secondly, the RFC says that if (IP is IPv6) then [IP], which in my view makes it mandatory to make absolutely sure that whatever I enclose within square brackets, is an IPv6 address and not anything else (even if invalid).

I've been considering all of the above right from my initial PR, including the fact that indexOf is faster than isIPv6. However, since all points of view express advantages and disadvantages, I also opted for net.isIPv6 in the end, because that allows my fix to avoid type assumptions and ultimately make the code terse, and enforces the RFC statement.

While the above explains my preference for net.isIPv6, if there's consensus on reverting it back to : matching, I'll happily do it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Secondly, the RFC says that if (IP is IPv6) then [IP], which in my view makes it mandatory to make absolutely sure that whatever I enclose within square bracket

It doesn't say that wrapping invalid host with brackets makes it more invalid, that's all I'm saying.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Doing a quick scan for two :'s may be a simple workaround here. I agree that dropping down to the native code to check is a bit overweight for this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yea, I agree. Just ran some benchmarks and net.isIPv6 runs about 3-6 times slower than an indexOf check here.

mpotra commented Feb 22, 2016

Copy link
Copy Markdown
Contributor Author

I've just pushed two commits with the following:

  • drop net.isIPv6 for indexOf(); checking for the presence of two colons, to avoid false positives when port is present. Reintroduced skipping when the hostname is already an IPv6 within square brackets.
  • Replaced string concatenation hostHeader = '[' + hostHeader +']' with string literal hostHeader = [${hostHeader}]``

Copy link
Copy Markdown
Contributor

jasnell commented Mar 2, 2016

Copy link
Copy Markdown
Member

Still LGTM. @nodejs/http @nodejs/ctc

jasnell commented Mar 21, 2016

Copy link
Copy Markdown
Member

@evanlucas ... does this LGTY?

Copy link
Copy Markdown
Contributor

LGTM

jasnell commented Mar 22, 2016

Copy link
Copy Markdown
Member

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

nit: would just make this const server

jasnell commented Mar 22, 2016

Copy link
Copy Markdown
Member

CI is green, added a small nit.

mpotra force-pushed the http-host-header-ipv6 branch from bc7d9ca to 6634168 Compare March 22, 2016 14:36

mpotra commented Mar 22, 2016

Copy link
Copy Markdown
Contributor Author

Modified to use const server

jasnell commented Mar 22, 2016

Copy link
Copy Markdown
Member

New CI after the rebase: https://ci.nodejs.org/job/node-test-pull-request/2021/

mpotra commented Mar 24, 2016

Copy link
Copy Markdown
Contributor Author

Apparently CI failed on "node-test-binary-arm » 3,pi1-raspbian-wheezy" https://ci.nodejs.org/job/node-test-binary-arm/1448//console
Could it be from my const server commit?

jasnell commented Mar 24, 2016

Copy link
Copy Markdown
Member

No, we've been seeing an increase in random flakiness with tests on the pi devices. I don't think the failure is related. /cc @nodejs/testing

jasnell commented Mar 24, 2016

Copy link
Copy Markdown
Member

Can I ask you to please squash the commits down into one commit now? Thank you!

mpotra commented Mar 24, 2016

Copy link
Copy Markdown
Contributor Author

Sure, done.

mpotra force-pushed the http-host-header-ipv6 branch from cebe453 to f311efd Compare March 25, 2016 11:28

mpotra commented Mar 25, 2016

Copy link
Copy Markdown
Contributor Author

Thanks, and sorry for having it under internet in the first place. It's adjusted now.

Copy link
Copy Markdown
Contributor

No problem at all. Sorry for just noticing :]

I've started another CI run: https://ci.nodejs.org/job/node-test-pull-request/2063/

IPv6 addresses in Host header (URI), must be enclosed within
square brackets, in order to properly separate the host address
from any port reference.

test: add test for IPv6 hostname conformance in Host header
http: Ensure IPv6 is enclosed within square brackets in Host header
http: use net.isIPv6 in ClientRequest
test: update test with const instead of var
test: use common.mustCall and cleanup
http: ClientRequest, drop isIPv6() in favor of indexOf() checks
http: ClientRequest, replace concatenation with string literal
test: use const
test: clean-up
test: move test to parallel
test: skip if no IPv6 support

mpotra commented Mar 25, 2016

Copy link
Copy Markdown
Contributor Author

Two failures: 1 is parallel/test-tls-sni-option on smartos, but the arm (p1/p2-raspbian) fails on my test:

not ok 61 test-http-host-header-ipv6-fail.js
# events.js:154
# throw er; // Unhandled 'error' event
# ^
# 
# Error: listen EAFNOSUPPORT ::1:12346
# at Object.exports._errnoException (util.js:893:11)
# at exports._exceptionWithHostPort (util.js:916:20)
# at Server._listen2 (net.js:1225:19)
# at listen (net.js:1274:10)
# at net.js:1384:9
# at _combinedTickCallback (internal/process/next_tick.js:77:11)
# at process._tickCallback (internal/process/next_tick.js:98:9)
# at Function.Module.runMain (module.js:453:11)
# at startup (node.js:155:18)
# at node.js:433:3

Apparently it cannot bind ::1 IPv6. Any suggestions?
I guess I should I check for IPv6 support within interfaces, first..

mpotra force-pushed the http-host-header-ipv6 branch from f311efd to 5132c30 Compare March 25, 2016 14:03

mpotra commented Mar 25, 2016

Copy link
Copy Markdown
Contributor Author

Updated with IPv6 check, as per nodejs/node-v0.x-archive#7983

Copy link
Copy Markdown
Contributor

mpotra commented Mar 30, 2016

Copy link
Copy Markdown
Contributor Author

Everything looks green, except a test-dns.js timeout, which is not related to this PR, on p2-raspbian`.

Let me know if there's anything else I can do.

jasnell commented Apr 1, 2016

Copy link
Copy Markdown
Member

LGTM

jasnell pushed a commit that referenced this pull request Apr 1, 2016
IPv6 addresses in Host header (URI), must be enclosed within
square brackets, in order to properly separate the host address
from any port reference.

PR-URL: #5314
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>

jasnell commented Apr 1, 2016

Copy link
Copy Markdown
Member

Landed in dabe1d5

jasnell closed this Apr 1, 2016
MylesBorins pushed a commit that referenced this pull request Apr 5, 2016
IPv6 addresses in Host header (URI), must be enclosed within
square brackets, in order to properly separate the host address
from any port reference.

PR-URL: #5314
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
MylesBorins pushed a commit that referenced this pull request Apr 5, 2016
Notable changes:

http:
  * Enclose IPv6 Host header in square brackets. This will enable
  proper seperation of the host adress from any port reference
  (Mihai Potra) #5314
path:
  * Make win32.isAbsolute more consistent (Brian White)
  #6028
This was referenced Apr 5, 2016
MylesBorins pushed a commit that referenced this pull request Apr 5, 2016
Notable changes:

http:
  * Enclose IPv6 Host header in square brackets. This will enable
  proper seperation of the host adress from any port reference
  (Mihai Potra) #5314

path:
  * Make win32.isAbsolute more consistent (Brian White)
  #6028

PR-URL: #6060
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
MylesBorins pushed a commit that referenced this pull request Apr 5, 2016
Notable changes:

http:
  * Enclose IPv6 Host header in square brackets. This will enable
  proper seperation of the host adress from any port reference
  (Mihai Potra) #5314

path:
  * Make win32.isAbsolute more consistent (Brian White)
  #6028

PR-URL: #6060
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
MylesBorins pushed a commit that referenced this pull request Apr 16, 2016
IPv6 addresses in Host header (URI), must be enclosed within
square brackets, in order to properly separate the host address
from any port reference.

PR-URL: #5314
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
MylesBorins pushed a commit that referenced this pull request Apr 22, 2016
IPv6 addresses in Host header (URI), must be enclosed within
square brackets, in order to properly separate the host address
from any port reference.

PR-URL: #5314
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
MylesBorins pushed a commit that referenced this pull request May 6, 2016
IPv6 addresses in Host header (URI), must be enclosed within
square brackets, in order to properly separate the host address
from any port reference.

PR-URL: #5314
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
MylesBorins pushed a commit that referenced this pull request May 18, 2016
IPv6 addresses in Host header (URI), must be enclosed within
square brackets, in order to properly separate the host address
from any port reference.

PR-URL: #5314
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
MylesBorins mentioned this pull request May 18, 2016
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

Labels

http Issues or PRs related to the http subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

http.request sends non-standard Host header when IP6 address + port is used

6 participants


Back | FazBrowse Home | New Git URL