Skip to content

Commit

Permalink
Merge branch 'security/host-check'
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Apr 22, 2017
2 parents 60e4727 + 8db5fd5 commit f3a4ac6
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
3 changes: 3 additions & 0 deletions client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ var onSocketMsg = {
console.error(strippedErrors[i]);
if(useErrorOverlay) overlay.showMessage(errors);
},
error: function(error) {
console.error(error);
},
close: function() {
log("error", "[WDS] Disconnected!");
sendMsg("Close");
Expand Down
44 changes: 43 additions & 1 deletion lib/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ function Server(compiler, options) {
this.headers = options.headers;
this.clientLogLevel = options.clientLogLevel;
this.clientOverlay = options.overlay;
this.disableHostCheck = !!options.disableHostCheck;
this.publicHost = options.public;
this.sockets = [];
this.contentBaseWatchers = [];

Expand All @@ -52,6 +54,12 @@ function Server(compiler, options) {
// Init express server
const app = this.app = new express();

app.all("*", (req, res, next) => {
if(this.checkHost(req.headers))
return next();
res.send("Invalid Host header");
});

// middleware for serving webpack bundle
this.middleware = webpackDevMiddleware(compiler, options);

Expand Down Expand Up @@ -389,8 +397,37 @@ Server.prototype.setContentHeaders = function(req, res, next) {
next();
}

Server.prototype.checkHost = function(headers) {
// allow user to opt-out this security check, at own risk
if(this.disableHostCheck) return true;

// get the Host header and extract hostname
// we don't care about port not matching
const hostHeader = headers.host;
if(!hostHeader) return false;
const idx = hostHeader.indexOf(":");
const hostname = idx >= 0 ? hostHeader.substr(0, idx) : hostHeader;

// always allow localhost host, for convience
if(hostname === "127.0.0.1" || hostname === "localhost") return true;

// allow hostname of listening adress
if(hostname === this.listenHostname) return true;

// also allow public hostname if provided
if(typeof this.publicHost === "string") {
const idxPublic = this.publicHost.indexOf(":");
const publicHostname = idxPublic >= 0 ? this.publicHost.substr(0, idx) : this.publicHost;
if(hostname === publicHostname) return true;
}

// disallow
return false;
}

// delegate listen call and init sockjs
Server.prototype.listen = function() {
Server.prototype.listen = function(port, hostname) {
this.listenHostname = hostname;
const returnValue = this.listeningApp.listen.apply(this.listeningApp, arguments);
const sockServer = sockjs.createServer({
// Use provided up-to-date sockjs-client
Expand All @@ -404,6 +441,11 @@ Server.prototype.listen = function() {
});
sockServer.on("connection", (conn) => {
if(!conn) return;
if(!this.checkHost(conn.headers)) {
this.sockWrite([conn], "error", "Invalid Host header");
conn.close();
return;
}
this.sockets.push(conn);

conn.on("close", () => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"spdy": "^3.4.1",
"strip-ansi": "^3.0.0",
"supports-color": "^3.1.1",
"webpack-dev-middleware": "^1.9.0",
"webpack-dev-middleware": "^1.10.2",
"yargs": "^6.0.0"
},
"devDependencies": {
Expand Down

0 comments on commit f3a4ac6

Please sign in to comment.