@@ -22,6 +22,8 @@ function Server(compiler, options) {
2222 this . hot = options . hot ;
2323 this . headers = options . headers ;
2424 this . clientLogLevel = options . clientLogLevel ;
25+ this . disableHostCheck = ! ! options . disableHostCheck ;
26+ this . publicHost = options . public ;
2527 this . sockets = [ ] ;
2628
2729 // Listening for events
@@ -50,6 +52,12 @@ function Server(compiler, options) {
5052 // Init express server
5153 var app = this . app = new express ( ) ;
5254
55+ app . all ( "*" , ( req , res , next ) => {
56+ if ( this . checkHost ( req . headers ) )
57+ return next ( ) ;
58+ res . send ( "Invalid Host header" ) ;
59+ } ) ;
60+
5361 // middleware for serving webpack bundle
5462 this . middleware = webpackDevMiddleware ( compiler , options ) ;
5563
@@ -319,8 +327,37 @@ Server.prototype.setContentHeaders = function(req, res, next) {
319327 next ( ) ;
320328}
321329
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+
322358// delegate listen call and init sockjs
323- Server . prototype . listen = function ( ) {
359+ Server . prototype . listen = function ( port , hostname ) {
360+ this . listenHostname = hostname ;
324361 this . listeningApp . listen . apply ( this . listeningApp , arguments ) ;
325362 var sockServer = sockjs . createServer ( {
326363 // Limit useless logs
@@ -332,6 +369,11 @@ Server.prototype.listen = function() {
332369 } ) ;
333370 sockServer . on ( "connection" , function ( conn ) {
334371 if ( ! conn ) return ;
372+ if ( ! this . checkHost ( conn . headers ) ) {
373+ this . sockWrite ( [ conn ] , "error" , "Invalid Host header" ) ;
374+ conn . close ( ) ;
375+ return ;
376+ }
335377 this . sockets . push ( conn ) ;
336378
337379 conn . on ( "close" , function ( ) {
0 commit comments