Skip to content

Commit f524306

Browse files
authored
url: throw on NULL in IPv6 hostname
Fixes: #39592 PR-URL: #42313 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 4aae536 commit f524306

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

lib/url.js

+30-22
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ function isIpv6Hostname(hostname) {
177177
// as IPv6 by isIpv6Hostname above
178178
//
179179
// [1]: https://url.spec.whatwg.org/#forbidden-host-code-point
180-
const forbiddenHostChars = /[\t\n\r #%/:<>?@[\\\]^|]/;
180+
const forbiddenHostChars = /[\0\t\n\r #%/:<>?@[\\\]^|]/;
181+
// For IPv6, permit '[', ']', and ':'.
182+
const forbiddenHostCharsIpv6 = /[\0\t\n\r #%/<>?@\\^|]/;
181183

182184
Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
183185
validateString(url, 'url');
@@ -400,27 +402,33 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
400402
this.hostname = this.hostname.toLowerCase();
401403
}
402404

403-
if (!ipv6Hostname && this.hostname !== '') {
404-
// IDNA Support: Returns a punycoded representation of "domain".
405-
// It only converts parts of the domain name that
406-
// have non-ASCII characters, i.e. it doesn't matter if
407-
// you call it with a domain that already is ASCII-only.
408-
409-
// Use lenient mode (`true`) to try to support even non-compliant
410-
// URLs.
411-
this.hostname = toASCII(this.hostname, true);
412-
413-
// Prevent two potential routes of hostname spoofing.
414-
// 1. If this.hostname is empty, it must have become empty due to toASCII
415-
// since we checked this.hostname above.
416-
// 2. If any of forbiddenHostChars appears in this.hostname, it must have
417-
// also gotten in due to toASCII. This is since getHostname would have
418-
// filtered them out otherwise.
419-
// Rather than trying to correct this by moving the non-host part into
420-
// the pathname as we've done in getHostname, throw an exception to
421-
// convey the severity of this issue.
422-
if (this.hostname === '' || forbiddenHostChars.test(this.hostname)) {
423-
throw new ERR_INVALID_URL(url);
405+
if (this.hostname !== '') {
406+
if (ipv6Hostname) {
407+
if (forbiddenHostCharsIpv6.test(this.hostname)) {
408+
throw new ERR_INVALID_URL(url);
409+
}
410+
} else {
411+
// IDNA Support: Returns a punycoded representation of "domain".
412+
// It only converts parts of the domain name that
413+
// have non-ASCII characters, i.e. it doesn't matter if
414+
// you call it with a domain that already is ASCII-only.
415+
416+
// Use lenient mode (`true`) to try to support even non-compliant
417+
// URLs.
418+
this.hostname = toASCII(this.hostname, true);
419+
420+
// Prevent two potential routes of hostname spoofing.
421+
// 1. If this.hostname is empty, it must have become empty due to toASCII
422+
// since we checked this.hostname above.
423+
// 2. If any of forbiddenHostChars appears in this.hostname, it must have
424+
// also gotten in due to toASCII. This is since getHostname would have
425+
// filtered them out otherwise.
426+
// Rather than trying to correct this by moving the non-host part into
427+
// the pathname as we've done in getHostname, throw an exception to
428+
// convey the severity of this issue.
429+
if (this.hostname === '' || forbiddenHostChars.test(this.hostname)) {
430+
throw new ERR_INVALID_URL(url);
431+
}
424432
}
425433
}
426434

test/parallel/test-url-parse-invalid-input.js

+4
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ assert.throws(() => { url.parse('http://%E0%A4%A@fail'); },
3737
return e.code === undefined;
3838
});
3939

40+
assert.throws(() => { url.parse('http://[127.0.0.1\x00c8763]:8000/'); },
41+
{ code: 'ERR_INVALID_URL', input: 'http://[127.0.0.1\x00c8763]:8000/' }
42+
);
43+
4044
if (common.hasIntl) {
4145
// An array of Unicode code points whose Unicode NFKD contains a "bad
4246
// character".

0 commit comments

Comments
 (0)