Skip to content

Commit

Permalink
feat: make allowedHosts accept localhost subdomains by default (#4357)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdufresne committed Sep 5, 2022
1 parent 088a318 commit 0a33e6a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
4 changes: 3 additions & 1 deletion lib/Server.js
Expand Up @@ -2987,12 +2987,14 @@ class Server {
// an IPv6-address in URLs,
// these are removed from the hostname in url.parse(),
// so we have the pure IPv6-address in hostname.
// always allow localhost host, for convenience (hostname === 'localhost')
// For convenience, always allow localhost (hostname === 'localhost')
// and its subdomains (hostname.endsWith(".localhost")).
// allow hostname of listening address (hostname === this.options.host)
const isValidHostname =
(hostname !== null && ipaddr.IPv4.isValid(hostname)) ||
(hostname !== null && ipaddr.IPv6.isValid(hostname)) ||
hostname === "localhost" ||
(hostname !== null && hostname.endsWith(".localhost")) ||
hostname === this.options.host;

if (isValidHostname) {
Expand Down
6 changes: 6 additions & 0 deletions test/e2e/__snapshots__/allowed-hosts.test.js.snap.webpack4
Expand Up @@ -18,6 +18,12 @@ exports[`allowed hosts check host headers should always allow \`localhost\` if o

exports[`allowed hosts check host headers should always allow \`localhost\` if options.allowedHosts is auto: response status 1`] = `200`;

exports[`allowed hosts check host headers should always allow \`localhost\` subdomain if options.allowedHosts is auto: console messages 1`] = `Array []`;

exports[`allowed hosts check host headers should always allow \`localhost\` subdomain if options.allowedHosts is auto: page errors 1`] = `Array []`;

exports[`allowed hosts check host headers should always allow \`localhost\` subdomain if options.allowedHosts is auto: response status 1`] = `200`;

exports[`allowed hosts check host headers should always allow any host if options.allowedHosts is all: console messages 1`] = `Array []`;

exports[`allowed hosts check host headers should always allow any host if options.allowedHosts is all: page errors 1`] = `Array []`;
Expand Down
6 changes: 6 additions & 0 deletions test/e2e/__snapshots__/allowed-hosts.test.js.snap.webpack5
Expand Up @@ -18,6 +18,12 @@ exports[`allowed hosts check host headers should always allow \`localhost\` if o

exports[`allowed hosts check host headers should always allow \`localhost\` if options.allowedHosts is auto: response status 1`] = `200`;

exports[`allowed hosts check host headers should always allow \`localhost\` subdomain if options.allowedHosts is auto: console messages 1`] = `Array []`;

exports[`allowed hosts check host headers should always allow \`localhost\` subdomain if options.allowedHosts is auto: page errors 1`] = `Array []`;

exports[`allowed hosts check host headers should always allow \`localhost\` subdomain if options.allowedHosts is auto: response status 1`] = `200`;

exports[`allowed hosts check host headers should always allow any host if options.allowedHosts is all: console messages 1`] = `Array []`;

exports[`allowed hosts check host headers should always allow any host if options.allowedHosts is all: page errors 1`] = `Array []`;
Expand Down
41 changes: 41 additions & 0 deletions test/e2e/allowed-hosts.test.js
Expand Up @@ -1209,6 +1209,47 @@ describe("allowed hosts", () => {
expect(pageErrors).toMatchSnapshot("page errors");
});

it("should always allow `localhost` subdomain if options.allowedHosts is auto", async () => {
const options = {
allowedHosts: "auto",
port: port1,
};

const headers = {
host: "app.localhost",
};

server = new Server(options, compiler);

await server.start();

({ page, browser } = await runBrowser());

page
.on("console", (message) => {
consoleMessages.push(message);
})
.on("pageerror", (error) => {
pageErrors.push(error);
});

const response = await page.goto(`http://127.0.0.1:${port1}/main.js`, {
waitUntil: "networkidle0",
});

if (!server.checkHeader(headers, "host")) {
throw new Error("Validation didn't fail");
}

expect(response.status()).toMatchSnapshot("response status");

expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
"console messages"
);

expect(pageErrors).toMatchSnapshot("page errors");
});

it("should always allow value from the `host` options if options.allowedHosts is auto", async () => {
const networkIP = Server.internalIPSync("v4");
const options = {
Expand Down

0 comments on commit 0a33e6a

Please sign in to comment.