Fix/xss (#6403)

* Fixed filenames not being escaped when editing files This allowed a possible XSS by naming a file in a particular way on your device. * Fixed HTML generation in webserver not escaping most things from req.query This would allow XSS through a very simple phishing attack * Added HtmlEscape to Mobile default as well * Added sanitization to SAML redirect and Twitter/Azure

Josiah Baldwin committed Sep 26, 2024 at 21:09 UTC 04c96eb2ff3dcc57f220faf8256a092d25009b2a
3 files changed +35 -31
views/default-mobile.handlebars
+2 -2
@@ -5895,7 +5895,7 @@
5895 downloadFile = { path: decodeURIComponent(x), file: decodeURIComponent(y), size: z, tsize: 0, data: '', state: 0, id: Math.random() }
5896 //console.log('p13downloadFileCancel', downloadFile);
5897 files.sendText({ action: 'download', sub: 'start', id: downloadFile.id, path: downloadFile.path });
5898 - setDialogMode(2, "Download File", 10, p13downloadFileCancel, '<div>' + downloadFile.file + '</div><br /><progress id=d2progressBar style=width:100% value=0 max=' + z + ' />');
5898 + setDialogMode(2, "Download File", 10, p13downloadFileCancel, '<div>' + HtmlEscape(downloadFile.file) + '</div><br /><progress id=d2progressBar style=width:100% value=0 max=' + z + ' />');
5899 }
5900
5901 // Called by the html page to cancel the download
@@ -6043,7 +6043,7 @@
6043 if (uploadFile.xfiles.length > uploadFile.xfilePtr) {
6044 uploadFile.xptr = 0;
6045 var file = uploadFile.xfiles[uploadFile.xfilePtr];
6046 - QH('p13dfileName', file.name);
6046 + QH('p13dfileName', HtmlEscape(file.name));
6047 Q('d2progressBar').max = file.size;
6048 Q('d2progressBar').value = 0;
6049 if (file.xdata == null) {
views/default.handlebars
+2 -2
@@ -11567,7 +11567,7 @@
11567 gdownloadFile = { path: decodeURIComponent(x), file: decodeURIComponent(y), size: z, tsize: 0, data: '', state: 0, id: Math.random(), tag: tag }
11568 //console.log('p13downloadFileCancel', gdownloadFile);
11569 files.sendText({ action: 'download', sub: 'start', id: gdownloadFile.id, path: gdownloadFile.path });
11570 - setDialogMode(2, "Download File", 10, p13downloadFileCancel, '<div>' + gdownloadFile.file + '</div><br /><progress id=d2progressBar style=width:100% value=0 max=' + z + ' />');
11570 + setDialogMode(2, "Download File", 10, p13downloadFileCancel, '<div>' + EscapeHtml(gdownloadFile.file) + '</div><br /><progress id=d2progressBar style=width:100% value=0 max=' + z + ' />');
11571 }
11572
11573 // Called by the html page to cancel the download
@@ -11738,7 +11738,7 @@
11738 if (uploadFile.xfiles.length > uploadFile.xfilePtr) {
11739 uploadFile.xptr = 0;
11740 var file = uploadFile.xfiles[uploadFile.xfilePtr];
11741 - QH('p13dfileName', file.name);
11741 + QH('p13dfileName', EscapeHtml(file.name));
11742 Q('d2progressBar').max = file.size;
11743 Q('d2progressBar').value = 0;
11744 if (file.xdata == null) {
webserver.js
+31 -27
@@ -814,6 +814,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
814 return parent.config.domains[''];
815 }
816
817 + function cleanReqQuery(req, res) {
818 +
819 + }
820 +
821 function handleLogoutRequest(req, res) {
822 const domain = checkUserIpAddress(req, res);
823 if (domain == null) { return; }
@@ -861,7 +865,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
865 }
866
867 // This is the default logout redirect to the login page
864 - if (req.query.key != null) { res.redirect(domain.url + 'login?key=' + req.query.key); } else { res.redirect(domain.url + 'login'); }
868 + if (req.query.key != null) { res.redirect(domain.url + 'login?key=' + encodeURIComponent(req.query.key)); } else { res.redirect(domain.url + 'login'); }
869 }
870
871 // Return an object with 2FA type if 2-step auth can be skipped
@@ -2081,7 +2085,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
2085 for (var i in obj.meshes) {
2086 if ((obj.meshes[i].domain == domain.id) && (obj.meshes[i].deleted == null) && (obj.meshes[i].invite != null) && (obj.meshes[i].invite.codes.indexOf(req.body.inviteCode) >= 0)) {
2087 // Send invitation link, valid for 1 minute.
2084 - res.redirect(domain.url + 'agentinvite?c=' + parent.encodeCookie({ a: 4, mid: i, f: obj.meshes[i].invite.flags, ag: obj.meshes[i].invite.ag, expire: 1 }, parent.invitationLinkEncryptionKey) + (req.query.key ? ('&key=' + req.query.key) : '') + (req.query.hide ? ('&hide=' + req.query.hide) : ''));
2088 + res.redirect(domain.url + 'agentinvite?c=' + parent.encodeCookie({ a: 4, mid: i, f: obj.meshes[i].invite.flags, ag: obj.meshes[i].invite.ag, expire: 1 }, parent.invitationLinkEncryptionKey) + (req.query.key ? ('&key=' + encodeURIComponent(req.query.key)) : '') + (req.query.hide ? ('&hide=' + encodeURIComponent(req.query.hide)) : ''));
2089 return;
2090 }
2091 }
@@ -2816,7 +2820,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
2820 //res.redirect(domain.url); // This does not handle cookie correctly.
2821 res.set('Content-Type', 'text/html');
2822 let url = domain.url;
2819 - if (Object.keys(req.query).length > 0) { url += "?" + Object.keys(req.query).map(function(key) { return key + "=" + encodeURIComponent(req.query[key]); }).join("&"); }
2823 + if (Object.keys(req.query).length > 0) { url += "?" + Object.keys(req.query).map(function(key) { return encodeURIComponent(key) + "=" + encodeURIComponent(req.query[key]); }).join("&"); }
2824 res.end('<html><head><meta http-equiv="refresh" content=0;url="' + url + '"></head><body></body></html>');
2825 }
2826
@@ -3027,7 +3031,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
3031 // If the request has a "meshmessengerid", redirect to MeshMessenger
3032 // This situation happens when you get a push notification for a chat session, but are not logged in.
3033 if (req.query.meshmessengerid != null) {
3030 - res.redirect(domain.url + 'messenger?id=' + req.query.meshmessengerid + ((req.query.key != null) ? ('&key=' + req.query.key) : ''));
3034 + res.redirect(domain.url + 'messenger?id=' + encodeURIComponent(req.query.meshmessengerid) + ((req.query.key != null) ? ('&key=' + encodeURIComponent(req.query.key)) : ''));
3035 return;
3036 }
3037
@@ -3507,7 +3511,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
3511 if ((node == null) || ((rights & 8) == 0) || ((rights != 0xFFFFFFFF) && ((rights & 512) != 0))) { res.redirect(domain.url + getQueryPortion(req)); return; }
3512
3513 var logoutcontrols = { name: user.name };
3510 - var extras = (req.query.key != null) ? ('&key=' + req.query.key) : '';
3514 + var extras = (req.query.key != null) ? ('&key=' + encodeURIComponent(req.query.key)) : '';
3515 if ((domain.ldap == null) && (domain.sspi == null) && (obj.args.user == null) && (obj.args.nousers != true)) { logoutcontrols.logoutUrl = (domain.url + 'logout?' + Math.random() + extras); } // If a default user is in use or no user mode, don't display the logout button
3516
3517 // Create a authentication cookie
@@ -3564,7 +3568,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
3568 if (req.session.userid.split('/')[1] != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
3569 var user = obj.users[req.session.userid];
3570 var logoutcontrols = { name: user.name };
3567 - var extras = (req.query.key != null) ? ('&key=' + req.query.key) : '';
3571 + var extras = (req.query.key != null) ? ('&key=' + encodeURIComponent(req.query.key)) : '';
3572 if ((domain.ldap == null) && (domain.sspi == null) && (obj.args.user == null) && (obj.args.nousers != true)) { logoutcontrols.logoutUrl = (domain.url + 'logout?' + Math.random() + extras); } // If a default user is in use or no user mode, don't display the logout button
3573 render(req, res, getRenderPage('terms', req, domain), getRenderArgs({ terms: encodeURIComponent(parent.configurationFiles['terms.txt'].toString()).split('\'').join('\\\''), logoutControls: encodeURIComponent(JSON.stringify(logoutcontrols)).replace(/'/g, '%27') }, req, domain));
3574 } else {
@@ -3583,7 +3587,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
3587 if (req.session.userid.split('/')[1] != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
3588 var user = obj.users[req.session.userid];
3589 var logoutcontrols = { name: user.name };
3586 - var extras = (req.query.key != null) ? ('&key=' + req.query.key) : '';
3590 + var extras = (req.query.key != null) ? ('&key=' + encodeURIComponent(req.query.key)) : '';
3591 if ((domain.ldap == null) && (domain.sspi == null) && (obj.args.user == null) && (obj.args.nousers != true)) { logoutcontrols.logoutUrl = (domain.url + 'logout?' + Math.random() + extras); } // If a default user is in use or no user mode, don't display the logout button
3592 render(req, res, getRenderPage('terms', req, domain), getRenderArgs({ terms: encodeURIComponent(data).split('\'').join('\\\''), logoutControls: encodeURIComponent(JSON.stringify(logoutcontrols)).replace(/'/g, '%27') }, req, domain));
3593 } else {
@@ -3598,7 +3602,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
3602 if (req.session.userid.split('/')[1] != domain.id) { req.session = null; res.redirect(domain.url + getQueryPortion(req)); return; } // Check if the session is for the correct domain
3603 var user = obj.users[req.session.userid];
3604 var logoutcontrols = { name: user.name };
3601 - var extras = (req.query.key != null) ? ('&key=' + req.query.key) : '';
3605 + var extras = (req.query.key != null) ? ('&key=' + encodeURIComponent(req.query.key)) : '';
3606 if ((domain.ldap == null) && (domain.sspi == null) && (obj.args.user == null) && (obj.args.nousers != true)) { logoutcontrols.logoutUrl = (domain.url + 'logout?' + Math.random() + extras); } // If a default user is in use or no user mode, don't display the logout button
3607 render(req, res, getRenderPage('terms', req, domain), getRenderArgs({ logoutControls: encodeURIComponent(JSON.stringify(logoutcontrols)).replace(/'/g, '%27') }, req, domain));
3608 } else {
@@ -3630,7 +3634,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
3634 var user2 = idSplit[4] + '/' + idSplit[5] + '/' + idSplit[6]
3635 if (!req.session || !req.session.userid) {
3636 // Redirect to login page
3633 - if (req.query.key != null) { res.redirect(domain.url + '?key=' + req.query.key + '&meshmessengerid=' + req.query.id); } else { res.redirect(domain.url + '?meshmessengerid=' + req.query.id); }
3637 + if (req.query.key != null) { res.redirect(domain.url + '?key=' + encodeURIComponent(req.query.key) + '&meshmessengerid=' + encodeURIComponent(req.query.id)); } else { res.redirect(domain.url + '?meshmessengerid=' + encodeURIComponent(req.query.id)); }
3638 return;
3639 }
3640 if ((req.session.userid != user1) && (req.session.userid != user2)) { res.sendStatus(404); return; }
@@ -5480,7 +5484,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
5484 meshsettings += 'MeshServer=local\r\n';
5485 if ((obj.args.localdiscovery != null) && (typeof obj.args.localdiscovery.key == 'string') && (obj.args.localdiscovery.key.length > 0)) { meshsettings += 'DiscoveryKey=' + obj.args.localdiscovery.key + '\r\n'; }
5486 }
5483 - if ((req.query.tag != null) && (typeof req.query.tag == 'string') && (obj.common.isAlphaNumeric(req.query.tag) == true)) { meshsettings += 'Tag=' + req.query.tag + '\r\n'; }
5487 + if ((req.query.tag != null) && (typeof req.query.tag == 'string') && (obj.common.isAlphaNumeric(req.query.tag) == true)) { meshsettings += 'Tag=' + encodeURIComponent(req.query.tag) + '\r\n'; }
5488 if ((req.query.installflags != null) && (req.query.installflags != 0) && (parseInt(req.query.installflags) == req.query.installflags)) { meshsettings += 'InstallFlags=' + parseInt(req.query.installflags) + '\r\n'; }
5489 }
5490 if (req.query.id == '10006') { // Assistant settings and customizations
@@ -5769,9 +5773,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
5773 agentinfo: agentinfo,
5774 filestats: filestats,
5775 currentAgent: agentinfo.hashhex.startsWith(fileSplit[1].toLowerCase()),
5772 - downloadUrl: req.originalUrl.split('?')[0] + '?dldump=' + file + (req.query.key ? ('&key=' + req.query.key) : ''),
5773 - deleteUrl: req.originalUrl.split('?')[0] + '?deldump=' + file + (req.query.key ? ('&key=' + req.query.key) : ''),
5774 - agentUrl: req.originalUrl.split('?')[0] + '?id=' + agentinfo.id + (req.query.key ? ('&key=' + req.query.key) : ''),
5776 + downloadUrl: req.originalUrl.split('?')[0] + '?dldump=' + file + (req.query.key ? ('&key=' + encodeURIComponent(req.query.key)) : ''),
5777 + deleteUrl: req.originalUrl.split('?')[0] + '?deldump=' + file + (req.query.key ? ('&key=' + encodeURIComponent(req.query.key)) : ''),
5778 + agentUrl: req.originalUrl.split('?')[0] + '?id=' + agentinfo.id + (req.query.key ? ('&key=' + encodeURIComponent(req.query.key)) : ''),
5779 time: new Date(filestats.ctime)
5780 });
5781 }
@@ -5787,7 +5791,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
5791 response += '<td>' + d.fileSplit[1].toLowerCase() + '</td><td>' + d.fileSplit[2] + '</td><td><a href="' + d.deleteUrl + '">Delete</a></td></tr>';
5792 }
5793 }
5790 - response += '</table><a href="' + req.originalUrl.split('?')[0] + (req.query.key ? ('?key=' + req.query.key) : '') + '">Mesh Agents</a></body></html>';
5794 + response += '</table><a href="' + req.originalUrl.split('?')[0] + (req.query.key ? ('?key=' + encodeURIComponent(req.query.key)) : '') + '">Mesh Agents</a></body></html>';
5795 res.send(response);
5796 return;
5797 }
@@ -5798,9 +5802,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
5802 var response = '<html><head><title>Mesh Agents Cores</title><style>table,th,td { border:1px solid black;border-collapse:collapse;padding:3px; }</style></head><body style=overflow:auto><table>';
5803 response += '<tr style="background-color:lightgray"><th>Name</th><th>Size</th><th>Comp</th><th>Decompressed Hash SHA384</th></tr>';
5804 for (var i in parent.defaultMeshCores) {
5801 - response += '<tr><td>' + i.split(' ').join('&nbsp;') + '</td><td style="text-align:right"><a download href="/meshagents?dlcore=' + i + '">' + parent.defaultMeshCores[i].length + (req.query.key ? ('?key=' + req.query.key) : '') + '</a></td><td style="text-align:right"><a download href="/meshagents?dlccore=' + i + (req.query.key ? ('?key=' + req.query.key) : '') + '">' + parent.defaultMeshCoresDeflate[i].length + '</a></td><td>' + Buffer.from(parent.defaultMeshCoresHash[i], 'binary').toString('hex') + '</td></tr>';
5805 + response += '<tr><td>' + i.split(' ').join('&nbsp;') + '</td><td style="text-align:right"><a download href="/meshagents?dlcore=' + i + '">' + parent.defaultMeshCores[i].length + (req.query.key ? ('?key=' + encodeURIComponent(req.query.key)) : '') + '</a></td><td style="text-align:right"><a download href="/meshagents?dlccore=' + i + (req.query.key ? ('?key=' + encodeURIComponent(req.query.key)) : '') + '">' + parent.defaultMeshCoresDeflate[i].length + '</a></td><td>' + Buffer.from(parent.defaultMeshCoresHash[i], 'binary').toString('hex') + '</td></tr>';
5806 }
5803 - response += '</table><a href="' + req.originalUrl.split('?')[0] + (req.query.key ? ('?key=' + req.query.key) : '') + '">Mesh Agents</a></body></html>';
5807 + response += '</table><a href="' + req.originalUrl.split('?')[0] + (req.query.key ? ('?key=' + encodeURIComponent(req.query.key)) : '') + '">Mesh Agents</a></body></html>';
5808 res.send(response);
5809 return;
5810 }
@@ -5809,7 +5813,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
5813 // Download mesh core
5814 var bin = parent.defaultMeshCores[req.query.dlcore];
5815 if ((bin == null) || (bin.length < 5)) { try { res.sendStatus(404); } catch (ex) { } return; }
5812 - setContentDispositionHeader(res, 'application/octet-stream', req.query.dlcore + '.js', null, 'meshcore.js');
5816 + setContentDispositionHeader(res, 'application/octet-stream', encodeURIComponent(req.query.dlcore) + '.js', null, 'meshcore.js');
5817 res.send(bin.slice(4));
5818 return;
5819 }
@@ -5832,18 +5836,18 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
5836 var agentinfo = obj.parent.meshAgentBinaries[agentid];
5837 if (domain.meshAgentBinaries && domain.meshAgentBinaries[agentid]) { argentInfo = domain.meshAgentBinaries[agentid]; }
5838 response += '<tr><td>' + agentinfo.id + '</td><td>' + agentinfo.desc.split(' ').join('&nbsp;') + '</td>';
5835 - response += '<td><a download href="' + originalUrl + '?id=' + agentinfo.id + (req.query.key ? ('&key=' + req.query.key) : '') + '">' + agentinfo.rname + '</a>';
5839 + response += '<td><a download href="' + originalUrl + '?id=' + agentinfo.id + (req.query.key ? ('&key=' + encodeURIComponent(req.query.key)) : '') + '">' + agentinfo.rname + '</a>';
5840 if ((user.siteadmin == 0xFFFFFFFF) || ((Array.isArray(obj.parent.config.settings.agentcoredumpusers)) && (obj.parent.config.settings.agentcoredumpusers.indexOf(user._id) >= 0))) {
5837 - if ((agentid == 3) || (agentid == 4)) { response += ', <a download href="' + originalUrl + '?id=' + agentinfo.id + '&pdb=1' + (req.query.key ? ('&key=' + req.query.key) : '') + '">PDB</a>'; }
5841 + if ((agentid == 3) || (agentid == 4)) { response += ', <a download href="' + originalUrl + '?id=' + agentinfo.id + '&pdb=1' + (req.query.key ? ('&key=' + encodeURIComponent(req.query.key)) : '') + '">PDB</a>'; }
5842 }
5839 - if (agentinfo.zdata != null) { response += ', <a download href="' + originalUrl + '?id=' + agentinfo.id + '&zip=1' + (req.query.key ? ('&key=' + req.query.key) : '') + '">ZIP</a>'; }
5843 + if (agentinfo.zdata != null) { response += ', <a download href="' + originalUrl + '?id=' + agentinfo.id + '&zip=1' + (req.query.key ? ('&key=' + encodeURIComponent(req.query.key)) : '') + '">ZIP</a>'; }
5844 response += '</td>';
5845 response += '<td>' + agentinfo.size + '</td><td>' + agentinfo.hashhex + '</td>';
5842 - response += '<td><a download href="' + originalUrl + '?meshcmd=' + agentinfo.id + (req.query.key ? ('&key=' + req.query.key) : '') + '">' + agentinfo.rname.replace('agent', 'cmd') + '</a></td></tr>';
5846 + response += '<td><a download href="' + originalUrl + '?meshcmd=' + agentinfo.id + (req.query.key ? ('&key=' + encodeURIComponent(req.query.key)) : '') + '">' + agentinfo.rname.replace('agent', 'cmd') + '</a></td></tr>';
5847 }
5848 response += '</table>';
5845 - response += '<a href="' + originalUrl + '?cores=1' + (req.query.key ? ('&key=' + req.query.key) : '') + '">MeshCores</a> ';
5846 - if (coreDumpsAllowed) { response += '<a href="' + originalUrl + '?dumps=1' + (req.query.key ? ('&key=' + req.query.key) : '') + '">MeshAgent Crash Dumps</a>'; }
5849 + response += '<a href="' + originalUrl + '?cores=1' + (req.query.key ? ('&key=' + encodeURIComponent(req.query.key)) : '') + '">MeshCores</a> ';
5850 + if (coreDumpsAllowed) { response += '<a href="' + originalUrl + '?dumps=1' + (req.query.key ? ('&key=' + encodeURIComponent(req.query.key)) : '') + '">MeshAgent Crash Dumps</a>'; }
5851 response += '</body></html>';
5852 res.send(response);
5853 return;
@@ -5915,7 +5919,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
5919 meshsettings += 'MeshServer=local\r\n';
5920 if ((obj.args.localdiscovery != null) && (typeof obj.args.localdiscovery.key == 'string') && (obj.args.localdiscovery.key.length > 0)) { meshsettings += 'DiscoveryKey=' + obj.args.localdiscovery.key + '\r\n'; }
5921 }
5918 - if ((req.query.tag != null) && (typeof req.query.tag == 'string') && (obj.common.isAlphaNumeric(req.query.tag) == true)) { meshsettings += 'Tag=' + req.query.tag + '\r\n'; }
5922 + if ((req.query.tag != null) && (typeof req.query.tag == 'string') && (obj.common.isAlphaNumeric(req.query.tag) == true)) { meshsettings += 'Tag=' + encodeURIComponent(req.query.tag) + '\r\n'; }
5923 if ((req.query.installflags != null) && (req.query.installflags != 0) && (parseInt(req.query.installflags) == req.query.installflags)) { meshsettings += 'InstallFlags=' + parseInt(req.query.installflags) + '\r\n'; }
5924 if ((domain.agentnoproxy === true) || (obj.args.lanonly == true)) { meshsettings += 'ignoreProxyFile=1\r\n'; }
5925 if (obj.args.agentconfig) { for (var i in obj.args.agentconfig) { meshsettings += obj.args.agentconfig[i] + '\r\n'; } }
@@ -6063,7 +6067,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6067 meshsettings += 'MeshServer=local\r\n';
6068 if ((obj.args.localdiscovery != null) && (typeof obj.args.localdiscovery.key == 'string') && (obj.args.localdiscovery.key.length > 0)) { meshsettings += 'DiscoveryKey=' + obj.args.localdiscovery.key + '\r\n'; }
6069 }
6066 - if ((req.query.tag != null) && (typeof req.query.tag == 'string') && (obj.common.isAlphaNumeric(req.query.tag) == true)) { meshsettings += 'Tag=' + req.query.tag + '\r\n'; }
6070 + if ((req.query.tag != null) && (typeof req.query.tag == 'string') && (obj.common.isAlphaNumeric(req.query.tag) == true)) { meshsettings += 'Tag=' + encodeURIComponent(req.query.tag) + '\r\n'; }
6071 if ((req.query.installflags != null) && (req.query.installflags != 0) && (parseInt(req.query.installflags) == req.query.installflags)) { meshsettings += 'InstallFlags=' + parseInt(req.query.installflags) + '\r\n'; }
6072 if ((domain.agentnoproxy === true) || (obj.args.lanonly == true)) { meshsettings += 'ignoreProxyFile=1\r\n'; }
6073 if (obj.args.agentconfig) { for (var i in obj.args.agentconfig) { meshsettings += obj.args.agentconfig[i] + '\r\n'; } }
@@ -6781,7 +6785,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6785 var url = req.url;
6786 if (url.indexOf('?') >= 0) { url += '&nmr=1'; } else { url += '?nmr=1'; } // Add this to the URL to prevent redirect loop.
6787 res.set('Content-Type', 'text/html');
6784 - res.end('<html><head><meta http-equiv="refresh" content=0;url="' + url + '"></head><body></body></html>');
6788 + res.end('<html><head><meta http-equiv="refresh" content=0;url="' + encodeURIComponent(url) + '"></head><body></body></html>');
6789 } else {
6790 domain.passport.authenticate('twitter-' + domain.id, { failureRedirect: domain.url })(req, res, function (err) { if (err != null) { console.log(err); } next(); });
6791 }
@@ -6831,7 +6835,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6835 var url = req.url;
6836 if (url.indexOf('?') >= 0) { url += '&nmr=1'; } else { url += '?nmr=1'; } // Add this to the URL to prevent redirect loop.
6837 res.set('Content-Type', 'text/html');
6834 - res.end('<html><head><meta http-equiv="refresh" content=0;url="' + url + '"></head><body></body></html>');
6838 + res.end('<html><head><meta http-equiv="refresh" content=0;url="' + encodeURIComponent(url) + '"></head><body></body></html>');
6839 } else {
6840 if (req.query.state != null) {
6841 var c = obj.parent.decodeCookie(req.query.state, obj.parent.loginCookieEncryptionKey, 10); // 10 minute timeout