Improvements to cookie ip checking error messages.

Ylian Saint-Hilaire committed Jan 26, 2020 at 10:05 UTC 9d3ac34ef94b9b67cfabfe9304cb8ae7860e7884
2 files changed +13 -9
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.4.7-x",
3 + "version": "0.4.7-y",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
webserver.js
+12 -8
@@ -535,7 +535,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
535 for (var i in cookies) {
536 if (cookies[i].startsWith('twofactor=')) {
537 var twoFactorCookie = obj.parent.decodeCookie(decodeURIComponent(cookies[i].substring(10)), obj.parent.loginCookieEncryptionKey, (30 * 24 * 60)); // 30 day timeout
538 - if ((twoFactorCookie != null) && ((twoFactorCookie.ip == null) || (twoFactorCookie.ip === cleanRemoteAddr(req.ip))) && (twoFactorCookie.userid == user._id)) { return false; }
538 + if ((twoFactorCookie != null) && (obj.args.cookieipcheck !== false) && ((twoFactorCookie.ip == null) || (twoFactorCookie.ip === cleanRemoteAddr(req.ip))) && (twoFactorCookie.userid == user._id)) { return false; }
539 }
540 }
541 }
@@ -1434,7 +1434,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1434 req.session.ip = req.ip; // Bind this session to the IP address of the request
1435 } else if (req.query.login && (obj.parent.loginCookieEncryptionKey != null)) {
1436 var loginCookie = obj.parent.decodeCookie(req.query.login, obj.parent.loginCookieEncryptionKey, 60); // 60 minute timeout
1437 - //if ((loginCookie != null) && (loginCookie.ip != null) && (loginCookie.ip != cleanRemoteAddr(req.ip))) { loginCookie = null; } // If the cookie if binded to an IP address, check here.
1437 + //if ((loginCookie != null) && (obj.args.cookieipcheck !== false) && (loginCookie.ip != null) && (loginCookie.ip != cleanRemoteAddr(req.ip))) { loginCookie = null; } // If the cookie if binded to an IP address, check here.
1438 if ((loginCookie != null) && (loginCookie.a == 3) && (loginCookie.u != null) && (loginCookie.u.split('/')[1] == domain.id)) {
1439 // If a login cookie was provided, setup the session here.
1440 parent.debug('web', 'handleRootRequestEx: cookie auth ok.');
@@ -2169,7 +2169,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2169 // If an authentication cookie is embedded in the form, use that.
2170 if ((fields != null) && (fields.auth != null) && (fields.auth.length == 1) && (typeof fields.auth[0] == 'string')) {
2171 var loginCookie = obj.parent.decodeCookie(fields.auth[0], obj.parent.loginCookieEncryptionKey, 60); // 60 minute timeout
2172 - if ((loginCookie != null) && (loginCookie.ip != null) && (loginCookie.ip != cleanRemoteAddr(req.ip))) { loginCookie = null; } // Check cookie IP binding.
2172 + if ((loginCookie != null) && (obj.args.cookieipcheck !== false) && (loginCookie.ip != null) && (loginCookie.ip != cleanRemoteAddr(req.ip))) { loginCookie = null; } // Check cookie IP binding.
2173 if ((loginCookie != null) && (domain.id == loginCookie.domainid)) { authUserid = loginCookie.userid; } // Use cookie authentication
2174 }
2175 if (authUserid == null) { res.sendStatus(401); return; }
@@ -2205,7 +2205,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2205 // If an authentication cookie is embedded in the form, use that.
2206 if ((fields != null) && (fields.auth != null) && (fields.auth.length == 1) && (typeof fields.auth[0] == 'string')) {
2207 var loginCookie = obj.parent.decodeCookie(fields.auth[0], obj.parent.loginCookieEncryptionKey, 60); // 60 minute timeout
2208 - if ((loginCookie != null) && (loginCookie.ip != null) && (loginCookie.ip != cleanRemoteAddr(req.ip))) { loginCookie = null; } // Check cookie IP binding.
2208 + if ((loginCookie != null) && (obj.args.cookieipcheck !== false) && (loginCookie.ip != null) && (loginCookie.ip != cleanRemoteAddr(req.ip))) { loginCookie = null; } // Check cookie IP binding.
2209 if ((loginCookie != null) && (domain.id == loginCookie.domainid)) { authUserid = loginCookie.userid; } // Use cookie authentication
2210 }
2211 if (authUserid == null) { res.sendStatus(401); return; }
@@ -3005,7 +3005,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3005 // If an authentication cookie is embedded in the form, use that.
3006 if ((fields != null) && (fields.auth != null) && (fields.auth.length == 1) && (typeof fields.auth[0] == 'string')) {
3007 var loginCookie = obj.parent.decodeCookie(fields.auth[0], obj.parent.loginCookieEncryptionKey, 60); // 60 minute timeout
3008 - if ((loginCookie != null) && (loginCookie.ip != null) && (loginCookie.ip != cleanRemoteAddr(req.ip))) { loginCookie = null; } // Check cookie IP binding.
3008 + if ((loginCookie != null) && (obj.args.cookieipcheck !== false) && (loginCookie.ip != null) && (loginCookie.ip != cleanRemoteAddr(req.ip))) { loginCookie = null; } // Check cookie IP binding.
3009 if ((loginCookie != null) && (domain.id == loginCookie.domainid)) { authUserid = loginCookie.userid; } // Use cookie authentication
3010 }
3011 if (authUserid == null) { res.sendStatus(401); return; }
@@ -3428,7 +3428,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3428
3429 // Add HTTP security headers to all responses
3430 obj.app.use(function (req, res, next) {
3431 - parent.debug('webrequest', req.url);
3431 + parent.debug('webrequest', '(' + cleanRemoteAddr(req.ip) + ') ' + req.url);
3432 res.removeHeader('X-Powered-By');
3433 var domain = req.xdomain = getDomain(req);
3434
@@ -3685,13 +3685,17 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
3685 // This is a encrypted cookie authentication
3686 var cookie = obj.parent.decodeCookie(req.query.auth, obj.parent.loginCookieEncryptionKey, 240); // Cookie with 4 hour timeout
3687 if ((cookie == null) && (obj.parent.multiServer != null)) { cookie = obj.parent.decodeCookie(req.query.auth, obj.parent.serverKey, 240); } // Try the server key
3688 - if ((cookie != null) && (cookie.ip != null) && (cookie.ip != cleanRemoteAddr(req.ip) && (cookie.ip != req.ip))) { cookie = null; } // If the cookie if binded to an IP address, check here.
3688 + if ((obj.args.cookieipcheck !== false) && (cookie != null) && (cookie.ip != null) && (cookie.ip != cleanRemoteAddr(req.ip) && (cookie.ip != req.ip))) { // If the cookie if binded to an IP address, check here.
3689 + parent.debug('web', 'ERR: Invalid cookie IP address, got \"' + cookie.ip + '\", expected \"' + cleanRemoteAddr(req.ip) + '\".');
3690 + cookie = null;
3691 + }
3692 if ((cookie != null) && (obj.users[cookie.userid]) && (cookie.domainid == domain.id)) {
3693 // Valid cookie, we are authenticated
3694 func(ws, req, domain, obj.users[cookie.userid], cookie);
3695 } else {
3696 // This is a bad cookie, keep going anyway, maybe we have a active session that will save us.
3694 - parent.debug('web', 'ERR: Websocket bad cookie auth: ' + req.query.auth);
3697 + if ((cookie != null) && (cookie.domainid != domain.id)) { parent.debug('web', 'ERR: Invalid domain, got \"' + cookie.domainid + '\", expected \"' + domain.id + '\".'); }
3698 + parent.debug('web', 'ERR: Websocket bad cookie auth (Cookie:' + (cookie != null) + '): ' + req.query.auth);
3699 try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'noauth-2' })); ws.close(); } catch (e) { }
3700 }
3701 return;