From 03b8482367a07d88c65387375b62497cb1f85fc4 Mon Sep 17 00:00:00 2001 From: Tom Dale and Yehuda Katz Date: Fri, 30 Jan 2015 15:16:22 -0800 Subject: [PATCH 1/2] Add hook for extracting protocol from URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to sanitize potentially dangerous URLs that contain executable behavior (e.g. “javascript:” URLs), we need to determine the protocol. Unfortunately, URL parsing is notoriously error-prone, so we want to use the host environment’s native functionality such that the protocol we report is the same as what it will act upon. In this case, we expose a `protocolForURL` hook that uses a generated `` element to set its `href` and check the resulting `protocol`. A Node.js implementation could fall back to using the `url` package that is included in the standard library. --- packages/morph/lib/dom-helper.js | 12 ++++++++++++ packages/morph/tests/dom-helper-test.js | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/morph/lib/dom-helper.js b/packages/morph/lib/dom-helper.js index 2b9a3aed..ea72f120 100644 --- a/packages/morph/lib/dom-helper.js +++ b/packages/morph/lib/dom-helper.js @@ -403,4 +403,16 @@ prototype.parseHTML = function(html, contextualElement) { } }; +var parsingNode; + +// Used to determine whether a URL needs to be sanitized. +prototype.protocolForURL = function(url) { + if (!parsingNode) { + parsingNode = this.document.createElement('a'); + } + + parsingNode.href = url; + return parsingNode.protocol; +}; + export default DOMHelper; diff --git a/packages/morph/tests/dom-helper-test.js b/packages/morph/tests/dom-helper-test.js index 44f17d9f..e7304975 100644 --- a/packages/morph/tests/dom-helper-test.js +++ b/packages/morph/tests/dom-helper-test.js @@ -372,6 +372,16 @@ test('#parseHTML of number', function(){ equalHTML(nodes, '5'); }); +test('#protocolForURL', function() { + var protocol = dom.protocolForURL("http://www.emberjs.com"); + equal(protocol, "http:"); + + // Inherit protocol from document if unparseable + protocol = dom.protocolForURL(" javascript :lulzhacked()"); + /*jshint scripturl:true*/ + equal(protocol, "http:"); +}); + test('#cloneNode shallow', function(){ var divElement = document.createElement('div'); From acb274d589cad1cec06fd872a50c74ed49aa3adc Mon Sep 17 00:00:00 2001 From: Tom Dale and Yehuda Katz Date: Fri, 30 Jan 2015 16:03:29 -0800 Subject: [PATCH 2/2] Fix protocol test --- packages/morph/tests/dom-helper-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/morph/tests/dom-helper-test.js b/packages/morph/tests/dom-helper-test.js index e7304975..8265180f 100644 --- a/packages/morph/tests/dom-helper-test.js +++ b/packages/morph/tests/dom-helper-test.js @@ -377,9 +377,9 @@ test('#protocolForURL', function() { equal(protocol, "http:"); // Inherit protocol from document if unparseable - protocol = dom.protocolForURL(" javascript :lulzhacked()"); + protocol = dom.protocolForURL(" javascript:lulzhacked()"); /*jshint scripturl:true*/ - equal(protocol, "http:"); + equal(protocol, "javascript:"); }); test('#cloneNode shallow', function(){