@@ -22,6 +22,8 @@ function Server(compiler, options) {
22
22
this . hot = options . hot ;
23
23
this . headers = options . headers ;
24
24
this . clientLogLevel = options . clientLogLevel ;
25
+ this . disableHostCheck = ! ! options . disableHostCheck ;
26
+ this . publicHost = options . public ;
25
27
this . sockets = [ ] ;
26
28
27
29
// Listening for events
@@ -50,6 +52,12 @@ function Server(compiler, options) {
50
52
// Init express server
51
53
var app = this . app = new express ( ) ;
52
54
55
+ app . all ( "*" , ( req , res , next ) => {
56
+ if ( this . checkHost ( req . headers ) )
57
+ return next ( ) ;
58
+ res . send ( "Invalid Host header" ) ;
59
+ } ) ;
60
+
53
61
// middleware for serving webpack bundle
54
62
this . middleware = webpackDevMiddleware ( compiler , options ) ;
55
63
@@ -319,8 +327,37 @@ Server.prototype.setContentHeaders = function(req, res, next) {
319
327
next ( ) ;
320
328
}
321
329
330
+ Server . prototype . checkHost = function ( headers ) {
331
+ // allow user to opt-out this security check, at own risk
332
+ if ( this . disableHostCheck ) return true ;
333
+
334
+ // get the Host header and extract hostname
335
+ // we don't care about port not matching
336
+ const hostHeader = headers . host ;
337
+ if ( ! hostHeader ) return false ;
338
+ const idx = hostHeader . indexOf ( ":" ) ;
339
+ const hostname = idx >= 0 ? hostHeader . substr ( 0 , idx ) : hostHeader ;
340
+
341
+ // always allow localhost host, for convience
342
+ if ( hostname === "127.0.0.1" || hostname === "localhost" ) return true ;
343
+
344
+ // allow hostname of listening adress
345
+ if ( hostname === this . listenHostname ) return true ;
346
+
347
+ // also allow public hostname if provided
348
+ if ( typeof this . publicHost === "string" ) {
349
+ const idxPublic = this . publicHost . indexOf ( ":" ) ;
350
+ const publicHostname = idxPublic >= 0 ? this . publicHost . substr ( 0 , idx ) : this . publicHost ;
351
+ if ( hostname === publicHostname ) return true ;
352
+ }
353
+
354
+ // disallow
355
+ return false ;
356
+ }
357
+
322
358
// delegate listen call and init sockjs
323
- Server . prototype . listen = function ( ) {
359
+ Server . prototype . listen = function ( port , hostname ) {
360
+ this . listenHostname = hostname ;
324
361
this . listeningApp . listen . apply ( this . listeningApp , arguments ) ;
325
362
var sockServer = sockjs . createServer ( {
326
363
// Limit useless logs
@@ -332,6 +369,11 @@ Server.prototype.listen = function() {
332
369
} ) ;
333
370
sockServer . on ( "connection" , function ( conn ) {
334
371
if ( ! conn ) return ;
372
+ if ( ! this . checkHost ( conn . headers ) ) {
373
+ this . sockWrite ( [ conn ] , "error" , "Invalid Host header" ) ;
374
+ conn . close ( ) ;
375
+ return ;
376
+ }
335
377
this . sockets . push ( conn ) ;
336
378
337
379
conn . on ( "close" , function ( ) {
0 commit comments