Skip to content

Commit da188a6

Browse files
usefulthinkshellscape
authored andcommitted
Handle IPv6-addresses correctly in checkHost() (#1026)
Add proper handling of IPv6-addresses to the checkHost()-method. Like IPv4-addresses, IPv6 addresses are always allowed.
1 parent 65f0586 commit da188a6

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

lib/Server.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const ip = require("ip");
1111
const serveIndex = require("serve-index");
1212
const historyApiFallback = require("connect-history-api-fallback");
1313
const path = require("path");
14+
const url = require("url");
1415
const selfsigned = require("selfsigned");
1516
const sockjs = require("sockjs");
1617
const spdy = require("spdy");
@@ -439,11 +440,15 @@ Server.prototype.checkHost = function(headers) {
439440
// we don't care about port not matching
440441
const hostHeader = headers.host;
441442
if(!hostHeader) return false;
442-
const idx = hostHeader.indexOf(":");
443-
const hostname = idx >= 0 ? hostHeader.substr(0, idx) : hostHeader;
444443

445-
// always allow requests with explicit IP-address
446-
if(ip.isV4Format(hostname)) return true;
444+
// use the node url-parser to retrieve the hostname from the host-header.
445+
const hostname = url.parse("//" + hostHeader, false, true).hostname;
446+
447+
// always allow requests with explicit IPv4 or IPv6-address.
448+
// A note on IPv6 addresses: hostHeader will always contain the brackets denoting
449+
// an IPv6-address in URLs, these are removed from the hostname in url.parse(),
450+
// so we have the pure IPv6-address in hostname.
451+
if(ip.isV4Format(hostname) || ip.isV6Format(hostname)) return true;
447452

448453
// always allow localhost host, for convience
449454
if(hostname === "localhost") return true;

test/Validation.test.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,22 @@ describe("Validation", function() {
113113

114114
it("should allow access for every requests using an IP", function() {
115115
const options = {};
116-
const headers = {
117-
host: "192.168.1.123"
118-
};
116+
const testHosts = [
117+
"192.168.1.123",
118+
"192.168.1.2:8080",
119+
"[::1]",
120+
"[::1]:8080",
121+
"[ad42::1de2:54c2:c2fa:1234]",
122+
"[ad42::1de2:54c2:c2fa:1234]:8080"
123+
];
124+
119125
const server = new Server(compiler, options);
120-
if(!server.checkHost(headers)) {
121-
throw new Error("Validation didn't fail");
122-
}
126+
testHosts.forEach(function(testHost) {
127+
const headers = { host: testHost };
128+
if(!server.checkHost(headers)) {
129+
throw new Error("Validation didn't pass");
130+
}
131+
});
123132
});
124133

125134
it("should not allow hostnames that don't match options.public", function() {

0 commit comments

Comments
 (0)