@@ -24,6 +24,22 @@ const webpackDevMiddleware = require('webpack-dev-middleware');
24
24
const OptionsValidationError = require ( './OptionsValidationError' ) ;
25
25
const optionsSchema = require ( './optionsSchema.json' ) ;
26
26
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
+
27
43
const clientStats = { errorDetails : false } ;
28
44
const log = console . log ; // eslint-disable-line no-console
29
45
@@ -510,17 +526,23 @@ Server.prototype.setContentHeaders = function (req, res, next) {
510
526
next ( ) ;
511
527
} ;
512
528
513
- Server . prototype . checkHost = function ( headers ) {
529
+ Server . prototype . checkHost = function ( headers , headerToCheck ) {
514
530
// allow user to opt-out this security check, at own risk
515
531
if ( this . disableHostCheck ) return true ;
516
532
533
+ if ( ! headerToCheck ) headerToCheck = 'host' ;
517
534
// get the Host header and extract hostname
518
535
// we don't care about port not matching
519
- const hostHeader = headers . host ;
536
+ const hostHeader = headers [ headerToCheck ] ;
520
537
if ( ! hostHeader ) return false ;
521
538
522
539
// 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 ;
524
546
525
547
// always allow requests with explicit IPv4 or IPv6-address.
526
548
// A note on IPv6 addresses: hostHeader will always contain the brackets denoting
@@ -581,8 +603,8 @@ Server.prototype.listen = function (port, hostname, fn) {
581
603
582
604
sockServer . on ( 'connection' , ( conn ) => {
583
605
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' ) ;
586
608
conn . close ( ) ;
587
609
return ;
588
610
}
0 commit comments