Skip to content

Commit 1dde16c

Browse files
committed
fix: migrate firewall to allowedHosts option
1 parent 2d68701 commit 1dde16c

16 files changed

+230
-200
lines changed

bin/cli-flags.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ module.exports = {
395395
negative: true,
396396
},
397397
{
398-
name: 'firewall',
398+
name: 'allowed-hosts',
399399
type: [Boolean, String],
400400
configs: [
401401
{
@@ -405,9 +405,8 @@ module.exports = {
405405
type: 'string',
406406
},
407407
],
408-
description:
409-
'Enable firewall or set hosts that are allowed to access the dev server.',
410-
negatedDescription: 'Disable firewall.',
408+
description: 'Set hosts that are allowed to access the dev server.',
409+
negatedDescription: 'Allow any host to access dev server.',
411410
multiple: true,
412411
negative: true,
413412
},

examples/cli/web-socket-url/webpack.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ module.exports = setup({
1212
client: {
1313
webSocketURL: 'ws://localhost:8080',
1414
},
15-
firewall: false,
15+
allowedHosts: true,
1616
},
1717
});

lib/Server.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -899,8 +899,8 @@ class Server {
899899

900900
checkHeaders(headers, headerToCheck) {
901901
// allow user to opt out of this security check, at their own risk
902-
// by explicitly disabling firewall
903-
if (!this.options.firewall) {
902+
// by explicitly enabling allowedHosts
903+
if (this.options.allowedHosts) {
904904
return true;
905905
}
906906

@@ -942,7 +942,7 @@ class Server {
942942
return true;
943943
}
944944

945-
const allowedHosts = this.options.firewall;
945+
const allowedHosts = this.options.allowedHosts;
946946

947947
// always allow localhost host, for convenience
948948
// allow if hostname is in allowedHosts

lib/options.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,14 @@
337337
"type": "object",
338338
"description": "Provide options to webpack-dev-middleware which handles webpack assets. https://webpack.js.org/configuration/dev-server/#devserverdevmiddleware"
339339
},
340-
"firewall": {
340+
"allowedHosts": {
341341
"anyOf": [
342342
{
343343
"type": "boolean"
344344
},
345+
{
346+
"type": "string"
347+
},
345348
{
346349
"type": "array",
347350
"items": {
@@ -350,7 +353,7 @@
350353
"minItems": 1
351354
}
352355
],
353-
"description": "Defines routes which are enabled by default, on by default and allows localhost. https://webpack.js.org/configuration/dev-server/#devserverfirewall"
356+
"description": "Defines routes which are enabled by default, on by default and allows localhost. https://webpack.js.org/configuration/dev-server/#devserverallowedhosts"
354357
},
355358
"headers": {
356359
"anyOf": [

lib/utils/normalizeOptions.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,12 @@ function normalizeOptions(compiler, options, logger) {
128128

129129
options.devMiddleware = options.devMiddleware || {};
130130

131-
if (typeof options.firewall === 'undefined') {
132-
// firewall is enabled by default
133-
options.firewall = true;
131+
if (typeof options.allowedHosts === 'undefined') {
132+
// allowedHosts is disabled by default
133+
options.allowedHosts = false;
134+
} else if (typeof options.allowedHosts === 'string') {
135+
// we store allowedHosts as array when supplied as string
136+
options.allowedHosts = [options.allowedHosts];
134137
}
135138

136139
if (typeof options.setupExitSignals === 'undefined') {

test/__snapshots__/validate-options.test.js.snap.webpack4

+17-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`options validate should throw an error on the "allowedHosts" option with '[]' value 1`] = `
4+
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
5+
- configuration.allowedHosts should be an non-empty array."
6+
`;
7+
8+
exports[`options validate should throw an error on the "allowedHosts" option with '123' value 1`] = `
9+
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
10+
- configuration.allowedHosts should be one of these:
11+
boolean | string | [string, ...] (should not have fewer than 1 item)
12+
-> Defines routes which are enabled by default, on by default and allows localhost. https://webpack.js.org/configuration/dev-server/#devserverallowedhosts
13+
Details:
14+
* configuration.allowedHosts should be a boolean.
15+
* configuration.allowedHosts should be a string.
16+
* configuration.allowedHosts should be an array:
17+
[string, ...] (should not have fewer than 1 item)"
18+
`;
19+
320
exports[`options validate should throw an error on the "bonjour" option with '' value 1`] = `
421
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
522
- configuration.bonjour should be one of these:
@@ -141,22 +158,6 @@ exports[`options validate should throw an error on the "devMiddleware" option wi
141158
-> Provide options to webpack-dev-middleware which handles webpack assets. https://webpack.js.org/configuration/dev-server/#devserverdevmiddleware"
142159
`;
143160

144-
exports[`options validate should throw an error on the "firewall" option with '' value 1`] = `
145-
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
146-
- configuration.firewall should be one of these:
147-
boolean | [string, ...] (should not have fewer than 1 item)
148-
-> Defines routes which are enabled by default, on by default and allows localhost. https://webpack.js.org/configuration/dev-server/#devserverfirewall
149-
Details:
150-
* configuration.firewall should be a boolean.
151-
* configuration.firewall should be an array:
152-
[string, ...] (should not have fewer than 1 item)"
153-
`;
154-
155-
exports[`options validate should throw an error on the "firewall" option with '[]' value 1`] = `
156-
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
157-
- configuration.firewall should be an non-empty array."
158-
`;
159-
160161
exports[`options validate should throw an error on the "headers" option with '1' value 1`] = `
161162
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
162163
- configuration.headers should be one of these:

test/__snapshots__/validate-options.test.js.snap.webpack5

+17-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`options validate should throw an error on the "allowedHosts" option with '[]' value 1`] = `
4+
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
5+
- configuration.allowedHosts should be an non-empty array."
6+
`;
7+
8+
exports[`options validate should throw an error on the "allowedHosts" option with '123' value 1`] = `
9+
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
10+
- configuration.allowedHosts should be one of these:
11+
boolean | string | [string, ...] (should not have fewer than 1 item)
12+
-> Defines routes which are enabled by default, on by default and allows localhost. https://webpack.js.org/configuration/dev-server/#devserverallowedhosts
13+
Details:
14+
* configuration.allowedHosts should be a boolean.
15+
* configuration.allowedHosts should be a string.
16+
* configuration.allowedHosts should be an array:
17+
[string, ...] (should not have fewer than 1 item)"
18+
`;
19+
320
exports[`options validate should throw an error on the "bonjour" option with '' value 1`] = `
421
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
522
- configuration.bonjour should be one of these:
@@ -141,22 +158,6 @@ exports[`options validate should throw an error on the "devMiddleware" option wi
141158
-> Provide options to webpack-dev-middleware which handles webpack assets. https://webpack.js.org/configuration/dev-server/#devserverdevmiddleware"
142159
`;
143160

144-
exports[`options validate should throw an error on the "firewall" option with '' value 1`] = `
145-
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
146-
- configuration.firewall should be one of these:
147-
boolean | [string, ...] (should not have fewer than 1 item)
148-
-> Defines routes which are enabled by default, on by default and allows localhost. https://webpack.js.org/configuration/dev-server/#devserverfirewall
149-
Details:
150-
* configuration.firewall should be a boolean.
151-
* configuration.firewall should be an array:
152-
[string, ...] (should not have fewer than 1 item)"
153-
`;
154-
155-
exports[`options validate should throw an error on the "firewall" option with '[]' value 1`] = `
156-
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
157-
- configuration.firewall should be an non-empty array."
158-
`;
159-
160161
exports[`options validate should throw an error on the "headers" option with '1' value 1`] = `
161162
"ValidationError: Invalid configuration object. Object has been initialized using a configuration object that does not match the API schema.
162163
- configuration.headers should be one of these:

test/cli/__snapshots__/cli.test.js.snap.webpack4

+3-3
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,9 @@ Options:
271271
Page Applications.
272272
--compress Enable gzip compression.
273273
--no-compress Disable gzip compression.
274-
--firewall [value...] Enable firewall or set hosts that are
275-
allowed to access the dev server.
276-
--no-firewall Disable firewall.
274+
--allowed-hosts [value...] Set hosts that are allowed to access the dev
275+
server.
276+
--no-allowed-hosts Allow any host to access dev server.
277277
--watch-files <value...> Watch static files for file changes.
278278

279279
Global options:

test/cli/__snapshots__/cli.test.js.snap.webpack5

+3-3
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,9 @@ Options:
272272
Page Applications.
273273
--compress Enable gzip compression.
274274
--no-compress Disable gzip compression.
275-
--firewall [value...] Enable firewall or set hosts that are
276-
allowed to access the dev server.
277-
--no-firewall Disable firewall.
275+
--allowed-hosts [value...] Set hosts that are allowed to access the dev
276+
server.
277+
--no-allowed-hosts Allow any host to access dev server.
278278
--watch-files <value...> Watch static files for file changes.
279279

280280
Global options:

test/cli/cli.test.js

+43
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,49 @@ describe('CLI', () => {
654654
.catch(done);
655655
});
656656

657+
describe('allowed-hosts', () => {
658+
it('--allowed-hosts', (done) => {
659+
testBin('--allowed-hosts')
660+
.then((output) => {
661+
expect(output.exitCode).toEqual(0);
662+
done();
663+
})
664+
.catch(done);
665+
});
666+
667+
it('--no-allowed-hosts', (done) => {
668+
testBin('--no-allowed-hosts')
669+
.then((output) => {
670+
expect(output.exitCode).toEqual(0);
671+
done();
672+
})
673+
.catch(done);
674+
});
675+
676+
it('--allowed-hosts string', (done) => {
677+
testBin('--allowed-hosts', 'testhost.com')
678+
.then((output) => {
679+
expect(output.exitCode).toEqual(0);
680+
done();
681+
})
682+
.catch(done);
683+
});
684+
685+
it('--allowed-hosts multiple', (done) => {
686+
testBin(
687+
'--allowed-hosts',
688+
'testhost.com',
689+
'--allowed-hosts',
690+
'testhost1.com'
691+
)
692+
.then((output) => {
693+
expect(output.exitCode).toEqual(0);
694+
done();
695+
})
696+
.catch(done);
697+
});
698+
});
699+
657700
it('--no-static-serve-index', (done) => {
658701
testBin('--no-static-serve-index')
659702
.then((output) => {

test/e2e/web-socket-server-and-url.test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ for (const webSocketServerType of webSocketServerTypes) {
6565
webSocketServer: webSocketServerType,
6666
port: devServerPort,
6767
host: devServerHost,
68-
firewall: false,
68+
allowedHosts: true,
6969
hot: true,
7070
};
7171

@@ -132,7 +132,7 @@ for (const webSocketServerType of webSocketServerTypes) {
132132
webSocketServer: webSocketServerType,
133133
port: devServerPort,
134134
host: devServerHost,
135-
firewall: false,
135+
allowedHosts: true,
136136
hot: true,
137137
};
138138

@@ -204,7 +204,7 @@ for (const webSocketServerType of webSocketServerTypes) {
204204
port: devServerPort,
205205
host: devServerHost,
206206
webSocketServer: webSocketServerType,
207-
firewall: false,
207+
allowedHosts: true,
208208
hot: true,
209209
static: true,
210210
};

test/server/Server.test.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -301,12 +301,12 @@ describe('Server', () => {
301301
});
302302
});
303303

304-
it('should always allow any host if options.firewall is disabled', () => {
304+
it('should always allow any host if options.allowedHosts is enabled', () => {
305305
const options = {
306306
client: {
307307
webSocketURL: 'ws://test.host:80',
308308
},
309-
firewall: false,
309+
allowedHosts: true,
310310
};
311311

312312
const headers = {
@@ -430,10 +430,10 @@ describe('Server', () => {
430430
}
431431
});
432432

433-
describe('firewall', () => {
434-
it('should allow hosts in firewall', () => {
433+
describe('allowedHosts', () => {
434+
it('should allow hosts in allowedHosts', () => {
435435
const tests = ['test.host', 'test2.host', 'test3.host'];
436-
const options = { firewall: tests };
436+
const options = { allowedHosts: tests };
437437
server = createServer(compiler, options);
438438
tests.forEach((test) => {
439439
const headers = { host: test };
@@ -443,8 +443,8 @@ describe('Server', () => {
443443
});
444444
});
445445

446-
it('should allow hosts that pass a wildcard in firewall', () => {
447-
const options = { firewall: ['.example.com'] };
446+
it('should allow hosts that pass a wildcard in allowedHosts', () => {
447+
const options = { allowedHosts: ['.example.com'] };
448448
server = createServer(compiler, options);
449449
const tests = [
450450
'www.example.com',

0 commit comments

Comments
 (0)