Skip to content
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

feat: make allowedHosts accept localhost subdomains by default #4357

Merged
merged 2 commits into from Sep 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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