From 11a063de129c85e63c56c1f57c439d8f0da36862 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Thu, 23 Feb 2017 19:37:29 +0100 Subject: [PATCH] sanitize strings coming from user inputs --- src/js/controller/HeaderController.js | 2 +- .../dialogs/BrowseLocalController.js | 5 +- .../dialogs/ImportImageController.js | 2 +- src/js/controller/settings/SaveController.js | 2 +- src/js/utils/Template.js | 47 +++++++++++++------ src/js/utils/TooltipFormatter.js | 3 +- src/templates/misc-templates.html | 2 +- 7 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/js/controller/HeaderController.js b/src/js/controller/HeaderController.js index 6705323..55823d5 100644 --- a/src/js/controller/HeaderController.js +++ b/src/js/controller/HeaderController.js @@ -31,7 +31,7 @@ } if (this.piskelName_) { - this.piskelName_.innerHTML = name; + this.piskelName_.textContent = name; } } catch (e) { console.warn('Could not update header : ' + e.message); diff --git a/src/js/controller/dialogs/BrowseLocalController.js b/src/js/controller/dialogs/BrowseLocalController.js index be559f6..ca050ad 100644 --- a/src/js/controller/dialogs/BrowseLocalController.js +++ b/src/js/controller/dialogs/BrowseLocalController.js @@ -48,7 +48,10 @@ keys.forEach((function (key) { var date = pskl.utils.DateUtils.format(key.date, '{{Y}}/{{M}}/{{D}} {{H}}:{{m}}'); - html += pskl.utils.Template.replace(this.localStorageItemTemplate_, {name : key.name, date : date}); + html += pskl.utils.Template.replace(this.localStorageItemTemplate_, { + name : key.name, + date : date + }); }).bind(this)); var tableBody_ = this.piskelList.get(0).tBodies[0]; diff --git a/src/js/controller/dialogs/ImportImageController.js b/src/js/controller/dialogs/ImportImageController.js index 8613e3f..cd59e96 100644 --- a/src/js/controller/dialogs/ImportImageController.js +++ b/src/js/controller/dialogs/ImportImageController.js @@ -135,7 +135,7 @@ this.importedImage_.onload = function () {}; var fileName = this.extractFileNameFromPath_(this.file_.name); - this.fileNameContainer.html(fileName); + this.fileNameContainer.text(fileName); this.fileNameContainer.attr('title', fileName); this.resizeWidth.val(w); diff --git a/src/js/controller/settings/SaveController.js b/src/js/controller/settings/SaveController.js index 4ea4523..dbabe52 100644 --- a/src/js/controller/settings/SaveController.js +++ b/src/js/controller/settings/SaveController.js @@ -62,7 +62,7 @@ ns.SaveController.prototype.insertSavePartials_ = function () { this.getPartials_().forEach(function (partial) { - pskl.utils.Template.insert(this.saveForm, 'beforeend', partial); + this.saveForm.insertAdjacentHTML('beforeend', pskl.utils.Template.get(partial)); }.bind(this)); }; diff --git a/src/js/utils/Template.js b/src/js/utils/Template.js index ade063b..e040dc8 100644 --- a/src/js/utils/Template.js +++ b/src/js/utils/Template.js @@ -16,23 +16,12 @@ }, createFromHTML : function (html) { - var dummyEl = document.createElement('div'); + var dummyEl = ns.Template._getDummyEl(); dummyEl.innerHTML = html; - return dummyEl.children[0]; - }, + var element = dummyEl.children[0]; + dummyEl.innerHTML = ''; - insert : function (parent, position, templateId, dict) { - var html = pskl.utils.Template.getAndReplace(templateId, dict); - parent.insertAdjacentHTML(position, html); - }, - - getAndReplace : function (templateId, dict) { - var result = ''; - var tpl = pskl.utils.Template.get(templateId); - if (tpl) { - result = pskl.utils.Template.replace(tpl, dict); - } - return result; + return element; }, replace : function (template, dict) { @@ -49,10 +38,38 @@ value = ''; } } + + // Sanitize all values expect if the key is surrounded by `!` + if (!/^!.*!$/.test(key)) { + value = ns.Template.sanitize(value); + } + template = template.replace(new RegExp('\\{\\{' + key + '\\}\\}', 'g'), value); } } return template; + }, + + /** + * Sanitize the provided string to make it safer for using in templates. + */ + sanitize : function (string) { + var dummyEl = ns.Template._getDummyEl(); + + // Apply the unsafe string as text content and + dummyEl.textContent = string; + var sanitizedString = dummyEl.innerHTML; + + dummyEl.innerHTML = ''; + + return sanitizedString; + }, + + _getDummyEl : function () { + if (!ns.Template._dummyEl) { + ns.Template._dummyEl = document.createElement('div'); + } + return ns.Template._dummyEl; } }; })(); diff --git a/src/js/utils/TooltipFormatter.js b/src/js/utils/TooltipFormatter.js index 3a3786a..73cb0e4 100644 --- a/src/js/utils/TooltipFormatter.js +++ b/src/js/utils/TooltipFormatter.js @@ -9,7 +9,8 @@ return pskl.utils.Template.replace(tpl, { helptext : helpText, shortcut : shortcut, - descriptors : this.formatDescriptors_(descriptors) + // Avoid sanitization for descriptors (markup) + '!descriptors!' : this.formatDescriptors_(descriptors) }); }; diff --git a/src/templates/misc-templates.html b/src/templates/misc-templates.html index 41fc2c0..f1a69cf 100644 --- a/src/templates/misc-templates.html +++ b/src/templates/misc-templates.html @@ -11,7 +11,7 @@