@@ -24,6 +24,22 @@ const webpackDevMiddleware = require('webpack-dev-middleware');
2424const OptionsValidationError = require ( './OptionsValidationError' ) ;
2525const optionsSchema = require ( './optionsSchema.json' ) ;
2626
27+ // Workaround for sockjs@~0.3.19
28+ // sockjs will remove Origin header, however Origin header is required for checking host.
29+ // See https://github.com/webpack/webpack-dev-server/issues/1604 for more information
30+ {
31+ // eslint-disable-next-line global-require
32+ const SockjsSession = require ( 'sockjs/lib/transport' ) . Session ;
33+ const decorateConnection = SockjsSession . prototype . decorateConnection ;
34+ SockjsSession . prototype . decorateConnection = function ( req ) {
35+ decorateConnection . call ( this , req ) ;
36+ const connection = this . connection ;
37+ if ( connection . headers && ! ( 'origin' in connection . headers ) && 'origin' in req . headers ) {
38+ connection . headers . origin = req . headers . origin ;
39+ }
40+ } ;
41+ }
42+
2743const clientStats = { errorDetails : false } ;
2844const log = console . log ; // eslint-disable-line no-console
2945
@@ -510,17 +526,23 @@ Server.prototype.setContentHeaders = function (req, res, next) {
510526 next ( ) ;
511527} ;
512528
513- Server . prototype . checkHost = function ( headers ) {
529+ Server . prototype . checkHost = function ( headers , headerToCheck ) {
514530 // allow user to opt-out this security check, at own risk
515531 if ( this . disableHostCheck ) return true ;
516532
533+ if ( ! headerToCheck ) headerToCheck = 'host' ;
517534 // get the Host header and extract hostname
518535 // we don't care about port not matching
519- const hostHeader = headers . host ;
536+ const hostHeader = headers [ headerToCheck ] ;
520537 if ( ! hostHeader ) return false ;
521538
522539 // use the node url-parser to retrieve the hostname from the host-header.
523- const hostname = url . parse ( `//${ hostHeader } ` , false , true ) . hostname ;
540+ const hostname = url . parse (
541+ // if hostHeader doesn't have scheme, add // for parsing.
542+ / ^ ( .+ : ) ? \/ \/ / . test ( hostHeader ) ? hostHeader : `//${ hostHeader } ` ,
543+ false ,
544+ true ,
545+ ) . hostname ;
524546
525547 // always allow requests with explicit IPv4 or IPv6-address.
526548 // A note on IPv6 addresses: hostHeader will always contain the brackets denoting
@@ -581,8 +603,8 @@ Server.prototype.listen = function (port, hostname, fn) {
581603
582604 sockServer . on ( 'connection' , ( conn ) => {
583605 if ( ! conn ) return ;
584- if ( ! this . checkHost ( conn . headers ) ) {
585- this . sockWrite ( [ conn ] , 'error' , 'Invalid Host header' ) ;
606+ if ( ! this . checkHost ( conn . headers ) || ! this . checkHost ( conn . headers , 'origin' ) ) {
607+ this . sockWrite ( [ conn ] , 'error' , 'Invalid Host/Origin header' ) ;
586608 conn . close ( ) ;
587609 return ;
588610 }
0 commit comments