From 834ac256e786ee69e4e7a183a39a22649ac0f8d4 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Fri, 26 Jun 2020 18:04:28 -0700 Subject: [PATCH] Improved HTML escaping. --- meshuser.js | 16 ++++++++-------- translate/translate.json | 7 +++++++ views/agentinvite.handlebars | 5 +++-- views/default-mobile.handlebars | 8 ++++---- views/default.handlebars | 24 ++++++++++++------------ 5 files changed, 34 insertions(+), 26 deletions(-) diff --git a/meshuser.js b/meshuser.js index d5ae12cb..f39d211c 100644 --- a/meshuser.js +++ b/meshuser.js @@ -4279,7 +4279,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } case 'distributeCore': { // This is only available when plugins are enabled since it could cause stress on the server - if ((user.siteadmin & 0xFFFFFFFF) == 0 || parent.parent.pluginHandler == null) break; // must be full admin with plugins enabled + if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled for (var i in command.nodes) { parent.sendMeshAgentCore(user, domain, command.nodes[i]._id, 'default'); } @@ -4287,14 +4287,14 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use } case 'plugins': { // Since plugin actions generally require a server restart, use the Full admin permission - if ((user.siteadmin & 0xFFFFFFFF) == 0 || parent.parent.pluginHandler == null) break; // must be full admin with plugins enabled + if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled parent.db.getPlugins(function(err, docs) { try { ws.send(JSON.stringify({ action: 'updatePluginList', list: docs, result: err })); } catch (ex) { } }); break; } case 'pluginLatestCheck': { - if ((user.siteadmin & 0xFFFFFFFF) == 0 || parent.parent.pluginHandler == null) break; // must be full admin with plugins enabled + if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled parent.parent.pluginHandler.getPluginLatest() .then(function(latest) { try { ws.send(JSON.stringify({ action: 'pluginVersionsAvailable', list: latest })); } catch (ex) { } @@ -4302,7 +4302,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use break; } case 'addplugin': { - if ((user.siteadmin & 0xFFFFFFFF) == 0 || parent.parent.pluginHandler == null) break; // must be full admin, plugins enabled + if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled try { parent.parent.pluginHandler.getPluginConfig(command.url) .then(parent.parent.pluginHandler.addPlugin) @@ -4319,7 +4319,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use break; } case 'installplugin': { - if ((user.siteadmin & 0xFFFFFFFF) == 0 || parent.parent.pluginHandler == null) break; // must be full admin, plugins enabled + if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled parent.parent.pluginHandler.installPlugin(command.id, command.version_only, null, function(){ parent.db.getPlugins(function(err, docs) { try { ws.send(JSON.stringify({ action: 'updatePluginList', list: docs, result: err })); } catch (ex) { } @@ -4330,7 +4330,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use break; } case 'disableplugin': { - if ((user.siteadmin & 0xFFFFFFFF) == 0 || parent.parent.pluginHandler == null) break; // must be full admin, plugins enabled + if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled parent.parent.pluginHandler.disablePlugin(command.id, function(){ parent.db.getPlugins(function(err, docs) { try { ws.send(JSON.stringify({ action: 'updatePluginList', list: docs, result: err })); } catch (ex) { } @@ -4341,7 +4341,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use break; } case 'removeplugin': { - if ((user.siteadmin & 0xFFFFFFFF) == 0 || parent.parent.pluginHandler == null) break; // must be full admin, plugins enabled + if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled parent.parent.pluginHandler.removePlugin(command.id, function(){ parent.db.getPlugins(function(err, docs) { try { ws.send(JSON.stringify({ action: 'updatePluginList', list: docs, result: err })); } catch (ex) { } @@ -4350,7 +4350,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use break; } case 'getpluginversions': { - if ((user.siteadmin & 0xFFFFFFFF) == 0 || parent.parent.pluginHandler == null) break; // must be full admin, plugins enabled + if ((user.siteadmin != 0xFFFFFFFF) || (parent.parent.pluginHandler == null)) break; // Must be full admin with plugins enabled parent.parent.pluginHandler.getPluginVersions(command.id) .then(function (versionInfo) { try { ws.send(JSON.stringify({ action: 'downgradePluginVersions', info: versionInfo, error: null })); } catch (ex) { } diff --git a/translate/translate.json b/translate/translate.json index e0c89b60..8551ffe9 100644 --- a/translate/translate.json +++ b/translate/translate.json @@ -297,6 +297,13 @@ "default.handlebars->27->171" ] }, + { + "en": "'", + "xloc": [ + "agentinvite.handlebars->3->4", + "agentinvite.handlebars->3->5" + ] + }, { "cs": "(", "de": "(", diff --git a/views/agentinvite.handlebars b/views/agentinvite.handlebars index 90f142ca..d46aabbe 100644 --- a/views/agentinvite.handlebars +++ b/views/agentinvite.handlebars @@ -144,7 +144,7 @@ var installFlags = '{{{installflags}}}'; var groupName = decodeURIComponent('{{{meshname}}}'); if (groupName != '') { - QH('groupname', format("Remote Agent Installation for {0}", groupName)); + QH('groupname', format("Remote Agent Installation for {0}", escapeHtml(groupName))); document.title = format("{0} - Agent Installation", groupName); } else { document.title = "Agent Installation"; @@ -295,7 +295,8 @@ function copyToClipLinuxUnInstall() { copyTextToClip(linuxUnInstall); } function copyTextToClip(txt) { function selectElementText(e) { if (document.selection) { var range = document.body.createTextRange(); range.moveToElementText(e); range.select(); } else if (window.getSelection) { var range = document.createRange(); range.selectNode(e); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); } } var e = document.createElement('DIV'); e.textContent = txt; document.body.appendChild(e); selectElementText(e); document.execCommand('copy'); e.remove(); } function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); }; - + function escapeHtml(string) { return String(string).replace(/[&<>"'`=\/]/g, function (s) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/', '`': '`', '=': '=' }[s]; }); }; + function escapeHtmlBreaks(string) { return String(string).replace(/[&<>"'`=\/]/g, function (s) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '/': '/', '`': '`', '=': '=', '\r': '
', '\n': '' }[s]; }); }; diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars index 0e6eed39..a5f43861 100644 --- a/views/default-mobile.handlebars +++ b/views/default-mobile.handlebars @@ -733,7 +733,7 @@ var webState = '{{{webstate}}}'; if (webState != '') { webState = JSON.parse(decodeURIComponent(webState)); } for (var i in webState) { localStorage.setItem(i, webState[i]); } - if (!webState.loctag) { delete localStorage.removeItem('loctag'); } + if (webState && !webState.loctag) { delete localStorage.removeItem('loctag'); } var urlargs = parseUriArgs(); if (urlargs.key && (isAlphaNumeric(urlargs.key) == false)) { delete urlargs.key; } @@ -1714,7 +1714,7 @@ if (filetreelinkpath != '') { filetreelinkpath += '/' + filetreelocation[i]; if (folderdepth > 2) { publicPath += '/' + filetreelocation[i]; } } } filetreex = filetreex.f[filetreelocation[i]]; - displayPath += ' / ' + (filetreex.n != null ? filetreex.n : filetreelocation[i]) + ''; + displayPath += ' / ' + EscapeHtml(filetreex.n != null ? filetreex.n : filetreelocation[i]) + ''; folderdepth++; } else { break; @@ -2435,7 +2435,7 @@ // Node tags var groupingTags = '' + "None" + ''; - if (node.tags != null) { groupingTags = ''; for (var i in node.tags) { groupingTags += '' + node.tags[i] + ''; } } + if (node.tags != null) { groupingTags = ''; for (var i in node.tags) { groupingTags += '' + EscapeHtml(node.tags[i]) + ''; } } if ((meshrights & 4) != 0) { x += addDeviceAttribute("Tags", '' + groupingTags + ''); } else { @@ -3224,7 +3224,7 @@ var x = p13filetree.path.split('\\'); p13filetreelocation = []; for (var i in x) { if (x[i] != '') { p13filetreelocation.push(x[i]); } } // Remove empty spaces - for (var i in p13filetreelocation) { displayPath += ' / ' + p13filetreelocation[i] + '' } // Setup the path we display + for (var i in p13filetreelocation) { displayPath += ' / ' + EscapeHtml(p13filetreelocation[i]) + '' } // Setup the path we display var newlinkpath = p13filetreelocation.join('/'); // Sort the files diff --git a/views/default.handlebars b/views/default.handlebars index 9835db1f..ab86ebd0 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -5352,12 +5352,12 @@ if ((node.agent != null) && (node.agent.tag != null)) { // Attribute: Mesh Agent Tag var tag = EscapeHtml(node.agent.tag); - if (tag.startsWith('mailto:')) { tag = '' + tag.substring(7) + ''; } + if (tag.startsWith('mailto:')) { tag = '' + EscapeHtml(tag.substring(7)) + ''; } x += addDeviceAttribute("Agent Tag", tag); } else if ((node.intelamt != null) && (node.intelamt.tag != null)) { // Attribute: Intel AMT Tag var tag = EscapeHtml(node.intelamt.tag); - if (tag.startsWith('mailto:')) { tag = '' + tag.substring(7) + ''; } + if (tag.startsWith('mailto:')) { tag = '' + EscapeHtml(tag.substring(7)) + ''; } x += addDeviceAttribute("Intel® AMT Tag", tag); } @@ -5416,7 +5416,7 @@ // Node grouping tags var groupingTags = '' + "None" + ''; - if (node.tags != null) { groupingTags = ''; for (var i in node.tags) { groupingTags += '' + node.tags[i] + ''; } } + if (node.tags != null) { groupingTags = ''; for (var i in node.tags) { groupingTags += '' + EscapeHtml(node.tags[i]) + ''; } } if ((meshrights & 4) != 0) { x += addDeviceAttribute('Tags', '' + groupingTags + ' '); } else { @@ -7522,7 +7522,7 @@ var x = p13filetree.path.split('\\'); p13filetreelocation = []; for (var i in x) { if (x[i] != '') { p13filetreelocation.push(x[i]); } } // Remove empty spaces - for (var i in p13filetreelocation) { displayPath += ' / ' + p13filetreelocation[i] + '' } // Setup the path we display + for (var i in p13filetreelocation) { displayPath += ' / ' + EscapeHtml(p13filetreelocation[i]) + '' } // Setup the path we display var newlinkpath = p13filetreelocation.join('/'); // Sort the files @@ -9941,7 +9941,7 @@ if (filetreelinkpath != '') { filetreelinkpath += '/' + filetreelocation[i]; if (folderdepth > 2) { publicPath += '/' + filetreelocation[i]; } } } filetreex = filetreex.f[filetreelocation[i]]; - displayPath += ' / ' + (filetreex.n != null?filetreex.n:filetreelocation[i]) + ''; + displayPath += ' / ' + EscapeHtml(filetreex.n != null?filetreex.n:filetreelocation[i]) + ''; folderdepth++; } else { break; @@ -10446,10 +10446,10 @@ if (user.email != null) { if (((features & 0x200000) == 0) || (user.email.toLowerCase() != user.name.toLowerCase())) { // Username & email are different - username += ', ' + user.email + '' + emailVerified; + username += ', ' + EscapeHtml(user.email) + '' + emailVerified; } else { // Username & email are the same - username += ' ' + emailVerified; + username += ' ' + emailVerified; } } @@ -11314,8 +11314,8 @@ if ((event != null) && (event.originalTarget != null) && (event.originalTarget.href != null)) return; var user = currentUser = users[decodeURIComponent(userid)]; if (user == null) { setDialogMode(0); go(4); return; } - QH('p30userName', user.name); - QH('p31userName', user.name); + QH('p30userName', EscapeHtml(user.name)); + QH('p31userName', EscapeHtml(user.name)); var self = (user._id == userinfo._id), activeSessions = 0; if (wssessions != null && wssessions[user._id]) { activeSessions = wssessions[user._id]; } @@ -11356,9 +11356,9 @@ } if (((user.siteadmin != 0xFFFFFFFF) || (userinfo.siteadmin == 0xFFFFFFFF))) { // If we are not site admin, we can't change a admin email. - x += addDeviceAttribute("Email", everify + email + ' ' + ' '); + x += addDeviceAttribute("Email", everify + email + ' ' + ' '); } else { - x += addDeviceAttribute("Email", everify + email + ' '); + x += addDeviceAttribute("Email", everify + email + ' '); } if ((features & 0x02000000) || (user.phone != null)) { // If SMS is enabled on the server or user has a phone number @@ -11383,7 +11383,7 @@ // Administrative Realms if ((userinfo.siteadmin == 0xFFFFFFFF) || (userinfo.siteadmin & 2)) { var xuserGroups = '' + "None" + ''; - if (user.groups) { xuserGroups = ''; for (var i in user.groups) { xuserGroups += '' + user.groups[i] + ''; } } + if (user.groups) { xuserGroups = ''; for (var i in user.groups) { xuserGroups += '' + EscapeHtml(user.groups[i]) + ''; } } x += addDeviceAttribute("Admin Realms", addLinkConditional(xuserGroups, 'showUserGroupDialog(event,"' + userid + '")', (userinfo.siteadmin == 0xFFFFFFFF) || ((userinfo.groups == null) && (userinfo._id != user._id) && (user.siteadmin != 0xFFFFFFFF)))); }