From 90199b029eb78dbc068e0445b1c4399430b5c5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Dobe=C5=A1?= Date: Sat, 24 May 2014 15:44:28 +0200 Subject: [PATCH] Mitigation of Mutation XSS attacks [WIP] [fixes #88] --- nette.ajax.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/nette.ajax.js b/nette.ajax.js index 4e74ebd..bfd86f7 100644 --- a/nette.ajax.js +++ b/nette.ajax.js @@ -441,12 +441,53 @@ $.nette.ext('snippets', { } else if (!back && $el.is('[data-ajax-prepend]')) { $el.prepend(html); } else { + this.setHtml($el, html); + } + }, + setHtml: function ($el, html) { + if (this.isMXSSMitigationPossible()) { + this.mitigateMXSS($el.get(0)); $el.html(html); + } else { + // ... @todo } }, escapeSelector: function (selector) { // thx to @uestla (https://github.com/uestla) return selector.replace(/[\!"#\$%&'\(\)\*\+,\.\/:;<=>\?@\[\\\]\^`\{\|\}~]/g, '\\$&'); + }, + mitigateMXSS: function (element) { + var that = this; + if (typeof element.innerHTML === 'string') { + Object.defineProperty(element, 'innerHTML', { + get: function () { return that.changeInnerHtmlHandler(this, 'innerHTML') }, + set: function (html) { + while (this.firstChild) { + this.removeChild(this.lastChild); + } + this.insertAdjacentHTML('afterBegin', html); + } + }); + } + }, + changeInnerHtmlHandler: function (element, type) { + var serializer = new XMLSerializer(); + var domstring = ''; + if (type === 'outerHTML') { + try { + domstring += serializer.serializeToString(element); + } catch(e) {} + } else { + for (var i in element.childNodes) { + try { + domstring += serializer.serializeToString(element.childNodes[i]); + } catch(e) {} + } + } + return domstring; + }, + isMXSSMitigationPossible: function () { + // ... @todo } });