diff --git a/public/novnc/app/ui.js b/public/novnc/app/ui.js index 59fa2921..0da8617b 100644 --- a/public/novnc/app/ui.js +++ b/public/novnc/app/ui.js @@ -17,7 +17,29 @@ import Keyboard from "../core/input/keyboard.js"; import RFB from "../core/rfb.js"; import * as WebUtil from "./webutil.js"; -function parseUriArgs() { var href = window.document.location.href; if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } var name, r = {}, parsedUri = href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; } +// String validation +function isAlphaNumeric(str) { return (str.match(/^[A-Za-z0-9]+$/) != null); }; +function isSafeString(str) { return ((typeof str == 'string') && (str.indexOf('<') == -1) && (str.indexOf('>') == -1) && (str.indexOf('&') == -1) && (str.indexOf('"') == -1) && (str.indexOf('\'') == -1) && (str.indexOf('+') == -1) && (str.indexOf('(') == -1) && (str.indexOf(')') == -1) && (str.indexOf('#') == -1) && (str.indexOf('%') == -1) && (str.indexOf(':') == -1) && (str.indexOf('-') == -1)) }; + +// Parse URL arguments, only keep safe values +function parseUriArgs() { + var href = window.document.location.href; + if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } + var name, r = {}, parsedUri = href.split(/[\?&|\=]/); + parsedUri.splice(0, 1); + for (x in parsedUri) { + switch (x % 2) { + case 0: { name = decodeURIComponent(parsedUri[x]); break; } + case 1: { + r[name] = decodeURIComponent(parsedUri[x]); + if (!isSafeString(r[name])) { delete r[name]; } else { var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } } + break; + } default: { break; } + } + } + return r; +} + var urlargs = parseUriArgs(); const UI = { diff --git a/public/scripts/common-0.0.1-min.js b/public/scripts/common-0.0.1-min.js index 38657eff..a63ac8c4 100644 --- a/public/scripts/common-0.0.1-min.js +++ b/public/scripts/common-0.0.1-min.js @@ -1 +1 @@ -function Q(t){return document.getElementById(t)}function QS(t){try{return Q(t).style}catch(t){}}function QE(t,r){try{Q(t).disabled=!r}catch(t){}}function QV(t,r){try{QS(t).display=r?"":"none"}catch(t){}}function QA(t,r){Q(t).innerHTML+=r}function QH(t,r){Q(t).innerHTML=r}function QC(t){try{return Q(t).classList}catch(t){}}function inputBoxFocus(t){Q(t).focus();var r=Q(t).value;Q(t).value="",Q(t).value=r}function ReadShort(t,r){return(t.charCodeAt(r)<<8)+t.charCodeAt(r+1)}function ReadShortX(t,r){return(t.charCodeAt(r+1)<<8)+t.charCodeAt(r)}function ReadInt(t,r){return 16777216*t.charCodeAt(r)+(t.charCodeAt(r+1)<<16)+(t.charCodeAt(r+2)<<8)+t.charCodeAt(r+3)}function ReadSInt(t,r){return(t.charCodeAt(r)<<24)+(t.charCodeAt(r+1)<<16)+(t.charCodeAt(r+2)<<8)+t.charCodeAt(r+3)}function ReadIntX(t,r){return 16777216*t.charCodeAt(r+3)+(t.charCodeAt(r+2)<<16)+(t.charCodeAt(r+1)<<8)+t.charCodeAt(r)}function ShortToStr(t){return String.fromCharCode(t>>8&255,255&t)}function ShortToStrX(t){return String.fromCharCode(255&t,t>>8&255)}function IntToStr(t){return String.fromCharCode(t>>24&255,t>>16&255,t>>8&255,255&t)}function IntToStrX(t){return String.fromCharCode(255&t,t>>8&255,t>>16&255,t>>24&255)}function MakeToArray(t){return t&&null!=t&&"object"!=typeof t?[t]:t}function SplitArray(t){return t.split(",")}function Clone(t){return JSON.parse(JSON.stringify(t))}function EscapeHtml(t){return"string"==typeof t?t.replace(/&/g,"&").replace(/>/g,">").replace(//g,">").replace(/").replace(/\n/g,"").replace(/\t/g,"  "):"boolean"==typeof t?t:"number"==typeof t?t:void 0}function ArrayElementMove(t,r,n){t.splice(n,0,t.splice(r,1)[0])}function ObjectToStringEx(t,r){var n="";if(0!=t&&(!t||null==t))return"(Null)";if(t instanceof Array)for(var e in t)n+="
"+gap(r)+"Item #"+e+": "+ObjectToStringEx(t[e],r+1);else if(t instanceof Object)for(var e in t)n+="
"+gap(r)+e+" = "+ObjectToStringEx(t[e],r+1);else n+=EscapeHtml(t);return n}function ObjectToStringEx2(t,r){var n="";if(0!=t&&(!t||null==t))return"(Null)";if(t instanceof Array)for(var e in t)n+="\r\n"+gap2(r)+"Item #"+e+": "+ObjectToStringEx2(t[e],r+1);else if(t instanceof Object)for(var e in t)n+="\r\n"+gap2(r)+e+" = "+ObjectToStringEx2(t[e],r+1);else n+=EscapeHtml(t);return n}function gap(t){for(var r="",n=0;n<4*t;n++)r+=" ";return r}function gap2(t){for(var r="",n=0;n<4*t;n++)r+=" ";return r}function ObjectToString(t){return ObjectToStringEx(t,0)}function ObjectToString2(t){return ObjectToStringEx2(t,0)}function hex2rstr(t){if("string"!=typeof t||0==t.length)return"";for(var r,n="",e=(""+t).match(/../g);r=e.shift();)n+=String.fromCharCode("0x"+r);return n}function char2hex(t){return(t+256).toString(16).substr(-2).toUpperCase()}function rstr2hex(t){var r,n="";for(r=0;r>8&255,255&t)}function ShortToStrX(t){return String.fromCharCode(255&t,t>>8&255)}function IntToStr(t){return String.fromCharCode(t>>24&255,t>>16&255,t>>8&255,255&t)}function IntToStrX(t){return String.fromCharCode(255&t,t>>8&255,t>>16&255,t>>24&255)}function MakeToArray(t){return t&&null!=t&&"object"!=typeof t?[t]:t}function SplitArray(t){return t.split(",")}function Clone(t){return JSON.parse(JSON.stringify(t))}function EscapeHtml(t){return"string"==typeof t?t.replace(/&/g,"&").replace(/>/g,">").replace(//g,">").replace(/").replace(/\n/g,"").replace(/\t/g,"  "):"boolean"==typeof t?t:"number"==typeof t?t:void 0}function ArrayElementMove(t,n,r){t.splice(r,0,t.splice(n,1)[0])}function ObjectToStringEx(t,n){var r="";if(0!=t&&(!t||null==t))return"(Null)";if(t instanceof Array)for(var e in t)r+="
"+gap(n)+"Item #"+e+": "+ObjectToStringEx(t[e],n+1);else if(t instanceof Object)for(var e in t)r+="
"+gap(n)+e+" = "+ObjectToStringEx(t[e],n+1);else r+=EscapeHtml(t);return r}function ObjectToStringEx2(t,n){var r="";if(0!=t&&(!t||null==t))return"(Null)";if(t instanceof Array)for(var e in t)r+="\r\n"+gap2(n)+"Item #"+e+": "+ObjectToStringEx2(t[e],n+1);else if(t instanceof Object)for(var e in t)r+="\r\n"+gap2(n)+e+" = "+ObjectToStringEx2(t[e],n+1);else r+=EscapeHtml(t);return r}function gap(t){for(var n="",r=0;r<4*t;r++)n+=" ";return n}function gap2(t){for(var n="",r=0;r<4*t;r++)n+=" ";return n}function ObjectToString(t){return ObjectToStringEx(t,0)}function ObjectToString2(t){return ObjectToStringEx2(t,0)}function hex2rstr(t){if("string"!=typeof t||0==t.length)return"";for(var n,r="",e=(""+t).match(/../g);n=e.shift();)r+=String.fromCharCode("0x"+n);return r}function char2hex(t){return(t+256).toString(16).substr(-2).toUpperCase()}function rstr2hex(t){var n,r="";for(n=0;n")&&-1==t.indexOf("&")&&-1==t.indexOf('"')&&-1==t.indexOf("'")&&-1==t.indexOf("+")&&-1==t.indexOf("(")&&-1==t.indexOf(")")&&-1==t.indexOf("#")&&-1==t.indexOf("%")&&-1==t.indexOf(":")&&-1==t.indexOf("-")}function parseUriArgs(){var t=window.document.location.href;t.endsWith("#")&&(t=t.substring(0,t.length-1));var n,r={},e=t.split(/[\?&|\=]/);for(o in e.splice(0,1),e)switch(o%2){case 0:n=decodeURIComponent(e[o]);break;case 1:if(r[n]=decodeURIComponent(e[o]),isSafeString(r[n])){var o=parseInt(r[n]);o==r[n]&&(r[n]=o)}else delete r[n]}return r}String.prototype.startsWith||(String.prototype.startsWith=function(t){return 0===this.lastIndexOf(t,0)}),String.prototype.endsWith||(String.prototype.endsWith=function(t){return-1!==this.indexOf(t,this.length-t.length)}) \ No newline at end of file diff --git a/public/scripts/common-0.0.1.js b/public/scripts/common-0.0.1.js index 7a1e1ea1..d7fe4eb9 100644 --- a/public/scripts/common-0.0.1.js +++ b/public/scripts/common-0.0.1.js @@ -110,4 +110,24 @@ function trademarks(x) { return x.replace(/\(R\)/g, '®').replace(/\(TM\)/g, function zeroPad(num, c) { if (c == null) { c = 2; } var s = "00000000" + num; return s.substr(s.length - c); } // String validation -function isAlphaNumeric(str) { return (str.match(/^[A-Za-z0-9]+$/) != null); }; \ No newline at end of file +function isAlphaNumeric(str) { return (str.match(/^[A-Za-z0-9]+$/) != null); }; +function isSafeString(str) { return ((typeof str == 'string') && (str.indexOf('<') == -1) && (str.indexOf('>') == -1) && (str.indexOf('&') == -1) && (str.indexOf('"') == -1) && (str.indexOf('\'') == -1) && (str.indexOf('+') == -1) && (str.indexOf('(') == -1) && (str.indexOf(')') == -1) && (str.indexOf('#') == -1) && (str.indexOf('%') == -1) && (str.indexOf(':') == -1) && (str.indexOf('-') == -1)) }; + +// Parse URL arguments, only keep safe values +function parseUriArgs() { + var href = window.document.location.href; + if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } + var name, r = {}, parsedUri = href.split(/[\?&|\=]/); + parsedUri.splice(0, 1); + for (x in parsedUri) { + switch (x % 2) { + case 0: { name = decodeURIComponent(parsedUri[x]); break; } + case 1: { + r[name] = decodeURIComponent(parsedUri[x]); + if (!isSafeString(r[name])) { delete r[name]; } else { var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } } + break; + } default: { break; } + } + } + return r; +} \ No newline at end of file diff --git a/translate/translate.json b/translate/translate.json index 1b9697e0..7cbdbe77 100644 --- a/translate/translate.json +++ b/translate/translate.json @@ -1120,6 +1120,12 @@ "default.handlebars->container->dialog->dialogBody->dialog7->d7meshkvm->5->d7bitmapscaling->13" ] }, + { + "en": "256 colors", + "xloc": [ + "player.handlebars->3->18" + ] + }, { "cs": "2-faktorové ověřování zapnuto", "de": "Zweifaktorauthentifizierung eingeschaltet", @@ -1472,6 +1478,12 @@ "default.handlebars->27->359" ] }, + { + "en": "65536 colors", + "xloc": [ + "player.handlebars->3->20" + ] + }, { "cs": "Stav přihlášení za 7 dnů", "de": "7-Tage-Anmelde-Status", @@ -5828,6 +5840,13 @@ "default.handlebars->27->741" ] }, + { + "en": "Color Quality", + "xloc": [ + "player.handlebars->3->17", + "player.handlebars->3->19" + ] + }, { "cs": "Sloupce", "de": "Spalten", @@ -9286,7 +9305,7 @@ "ru": "Перетащите .mcrec файл или нажмите \\\"Открыть файл ... \\\"", "zh-chs": "拖放.mcrec文件或單擊 “打開文件...”", "xloc": [ - "player.handlebars->3->20" + "player.handlebars->3->25" ] }, { @@ -12831,7 +12850,7 @@ "ru": "Индексируется каждые {0} секунд", "zh-chs": "每{0}秒索引一次", "xloc": [ - "player.handlebars->3->17" + "player.handlebars->3->22" ] }, { @@ -13307,6 +13326,12 @@ "xterm.handlebars->9->5" ] }, + { + "en": "Intel® AMT KVM", + "xloc": [ + "player.handlebars->3->15" + ] + }, { "cs": "Intel® AMT zásada", "de": "Intel® AMT Regelwerk", @@ -19281,7 +19306,7 @@ "ru": "Открыть файл...", "zh-chs": "打開文件...", "xloc": [ - "player.handlebars->3->21", + "player.handlebars->3->26", "player.handlebars->p11->deskarea0->deskarea1->3" ] }, @@ -20618,8 +20643,8 @@ "ru": "Нажмите [пробел] для проигрывания/паузы.", "zh-chs": "按[空格]播放/暫停。", "xloc": [ - "player.handlebars->3->18", - "player.handlebars->3->19" + "player.handlebars->3->23", + "player.handlebars->3->24" ] }, { @@ -20716,7 +20741,7 @@ "zh-chs": "協議", "xloc": [ "default.handlebars->27->1718", - "player.handlebars->3->15" + "player.handlebars->3->16" ] }, { @@ -22862,7 +22887,7 @@ "ru": "Ищу", "zh-chs": "尋求", "xloc": [ - "player.handlebars->3->16" + "player.handlebars->3->21" ] }, { diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars index 19ee0347..0e6eed39 100644 --- a/views/default-mobile.handlebars +++ b/views/default-mobile.handlebars @@ -4212,7 +4212,6 @@ function joinPaths() { var x = []; for (var i in arguments) { var w = arguments[i]; if ((w != null) && (w != '')) { while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } x.push(w); } } return x.join('/'); } function focusTextBox(x) { setTimeout(function () { Q(x).selectionStart = Q(x).selectionEnd = 65535; Q(x).focus(); }, 0); } var isFilenameValid = (function () { var x1 = /^[^\\/:\*\?"<>\|]+$/, x2 = /^\./, x3 = /^(nul|prn|con|lpt[0-9]|com[0-9])(\.|$)/i; return function isFilenameValid(fname) { return x1.test(fname) && !x2.test(fname) && !x3.test(fname) && (fname[0] != '.'); } })(); - function parseUriArgs() { var href = window.document.location.href; if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } var name, r = {}, parsedUri = href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; } function printDate(d) { return d.toLocaleDateString(args.locale); } function printTime(d) { return d.toLocaleTimeString(args.locale); } function printDateTime(d) { return d.toLocaleString(args.locale); } diff --git a/views/default.handlebars b/views/default.handlebars index 5d462c56..c9fcccb2 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -12871,7 +12871,6 @@ function addHtmlValue2(t, v) { return '
' + v + '
' + t + '
'; } function addHtmlValue3(t, v) { return '
' + t + '
' + v + '
'; } function addHtmlValue4(t, v) { return '
' + t + '' + v + '
'; } - function parseUriArgs() { var href = window.document.location.href; if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } var name, r = {}, parsedUri = href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; } function focusTextBox(x) { setTimeout(function(){ Q(x).selectionStart = Q(x).selectionEnd = 65535; Q(x).focus(); }, 0); } function validateEmail(v) { var emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return emailReg.test(v); } // New version function isPrivateIP(a) { return (a.startsWith('10.') || a.startsWith('172.16.') || a.startsWith('192.168.')); } diff --git a/views/invite.handlebars b/views/invite.handlebars index 08a033f1..a00e3cbe 100644 --- a/views/invite.handlebars +++ b/views/invite.handlebars @@ -102,6 +102,7 @@ diff --git a/views/login.handlebars b/views/login.handlebars index ad2cfeb9..8d66a0f4 100644 --- a/views/login.handlebars +++ b/views/login.handlebars @@ -854,7 +854,6 @@ function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } } 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 addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '' + subtext + '' + text.substring(i + subtext.length); } - function parseUriArgs() { var href = window.document.location.href; if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } var name, r = {}, parsedUri = href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; } function addHtmlValue(t, v) { return '
' + t + '' + v + '
'; } diff --git a/views/messenger.handlebars b/views/messenger.handlebars index 362dfe56..9b19ed24 100644 --- a/views/messenger.handlebars +++ b/views/messenger.handlebars @@ -68,7 +68,7 @@ var currentFileDownload = null; // Set the title - if (args.title) { QH('xtitle', args.title.split(' ').join(' ')); document.title = document.title + ' - ' + args.title; } + if (args.title) { QH('xtitle', EscapeHtml(args.title).split(' ').join(' ')); document.title = document.title + ' - ' + args.title; } // Setup web notifications if (Notification) { QV('notifyButton', Notification.permission != 'granted'); } @@ -149,7 +149,7 @@ // Display a control message function displayControl(msg) { - QA('xmsg', '
' + msg + '
'); + QA('xmsg', '
' + EscapeHtml(msg) + '
'); Q('xmsg').scrollTop = Q('xmsg').scrollHeight; } @@ -163,7 +163,7 @@ // Display a message from the remote user function displayRemote(msg) { - QA('xmsg', '
' + msg + '
'); + QA('xmsg', '
' + EscapeHtml(msg) + '
'); Q('xmsg').scrollTop = Q('xmsg').scrollHeight; // If web notifications are granted, use it. @@ -185,14 +185,13 @@ var outtext = Q('xouttext').value; if (outtext.length > 0) { Q('xouttext').value = ''; - QA('xmsg', '
' + outtext + '
'); + QA('xmsg', '
' + EscapeHtml(outtext) + '
'); Q('xmsg').scrollTop = Q('xmsg').scrollHeight; send({ action: 'chat', msg: outtext }); } } function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; } - function parseUriArgs() { var name, r = {}, parsedUri = window.document.location.href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; } // Update user controls function updateControls() { diff --git a/views/mstsc.handlebars b/views/mstsc.handlebars index d8d6ff59..e7be6746 100644 --- a/views/mstsc.handlebars +++ b/views/mstsc.handlebars @@ -68,6 +68,7 @@ var client = null; var canvas = null; var urlargs = parseUriArgs(); + if (urlargs.key && (isAlphaNumeric(urlargs.key) == false)) { delete urlargs.key; } var cookie = '{{{cookie}}}'; var name = decodeURIComponent('{{{name}}}'); if (name != '') { document.title = name + ' - ' + document.title; } @@ -105,9 +106,31 @@ function QA(x, y) { Q(x).innerHTML += y; } // "Q" append function QH(x, y) { Q(x).innerHTML = y; } // "Q" html function QC(x) { try { return Q(x).classList; } catch (x) { } } // "Q" class - function parseUriArgs() { var href = window.document.location.href; if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } var name, r = {}, parsedUri = href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; } function EscapeHtml(x) { if (typeof x == 'string') return x.replace(/&/g, '&').replace(/>/g, '>').replace(//g, '>').replace(/').replace(/\n/g, '').replace(/\t/g, '  '); if (typeof x == 'boolean') return x; if (typeof x == 'number') return x; } + + // String validation + function isAlphaNumeric(str) { return (str.match(/^[A-Za-z0-9]+$/) != null); }; + function isSafeString(str) { return ((typeof str == 'string') && (str.indexOf('<') == -1) && (str.indexOf('>') == -1) && (str.indexOf('&') == -1) && (str.indexOf('"') == -1) && (str.indexOf('\'') == -1) && (str.indexOf('+') == -1) && (str.indexOf('(') == -1) && (str.indexOf(')') == -1) && (str.indexOf('#') == -1) && (str.indexOf('%') == -1) && (str.indexOf(':') == -1) && (str.indexOf('-') == -1)) }; + + // Parse URL arguments, only keep safe values + function parseUriArgs() { + var href = window.document.location.href; + if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } + var name, r = {}, parsedUri = href.split(/[\?&|\=]/); + parsedUri.splice(0, 1); + for (x in parsedUri) { + switch (x % 2) { + case 0: { name = decodeURIComponent(parsedUri[x]); break; } + case 1: { + r[name] = decodeURIComponent(parsedUri[x]); + if (!isSafeString(r[name])) { delete r[name]; } else { var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } } + break; + } default: { break; } + } + } + return r; + } diff --git a/views/terms.handlebars b/views/terms.handlebars index 00ac068c..80e3bd53 100644 --- a/views/terms.handlebars +++ b/views/terms.handlebars @@ -173,10 +173,8 @@ // Fix links if a loginKey if used var urlargs = parseUriArgs(); - if (urlargs.key) { - console.log('aa', urlargs.key); - Q('backLink').href += '?key=' + urlargs.key; - } + if (urlargs.key && (isAlphaNumeric(urlargs.key) == false)) { delete urlargs.key; } + if (urlargs.key) { Q('backLink').href += '?key=' + urlargs.key; } // Setup logout control var logoutControl = ''; @@ -250,8 +248,6 @@ function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } } function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } } 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 parseUriArgs() { var href = window.document.location.href; if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } var name, r = {}, parsedUri = href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; } - diff --git a/views/xterm.handlebars b/views/xterm.handlebars index 0f6df002..e883f3f6 100644 --- a/views/xterm.handlebars +++ b/views/xterm.handlebars @@ -92,6 +92,7 @@ function start() { // Parse any URL arguments args = parseUriArgs(); + if (args.key && (isAlphaNumeric(args.key) == false)) { delete args.key; } // Connect to the mesh server meshserver = MeshServerCreateControl(domainUrl, authCookie); @@ -303,7 +304,27 @@ function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; } function pad2(num) { var s = '00' + num; return s.substr(s.length - 2); } 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 parseUriArgs() { var name, r = {}, parsedUri = window.document.location.href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; } + function isAlphaNumeric(str) { return (str.match(/^[A-Za-z0-9]+$/) != null); }; + function isSafeString(str) { return ((typeof str == 'string') && (str.indexOf('<') == -1) && (str.indexOf('>') == -1) && (str.indexOf('&') == -1) && (str.indexOf('"') == -1) && (str.indexOf('\'') == -1) && (str.indexOf('+') == -1) && (str.indexOf('(') == -1) && (str.indexOf(')') == -1) && (str.indexOf('#') == -1) && (str.indexOf('%') == -1) && (str.indexOf(':') == -1) && (str.indexOf('-') == -1)) }; + + // Parse URL arguments, only keep safe values + function parseUriArgs() { + var href = window.document.location.href; + if (href.endsWith('#')) { href = href.substring(0, href.length - 1); } + var name, r = {}, parsedUri = href.split(/[\?&|\=]/); + parsedUri.splice(0, 1); + for (x in parsedUri) { + switch (x % 2) { + case 0: { name = decodeURIComponent(parsedUri[x]); break; } + case 1: { + r[name] = decodeURIComponent(parsedUri[x]); + if (!isSafeString(r[name])) { delete r[name]; } else { var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } } + break; + } default: { break; } + } + } + return r; + } start();