diff --git a/package.json b/package.json index b1c068a488a..77b2faf74f0 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "express": "^4.5.0", "github": "^0.2.3", "glob": "~4.3.2", - "htmlbars": "0.11.1", + "htmlbars": "0.11.2", "qunit-extras": "^1.3.0", "qunitjs": "^1.16.0", "route-recognizer": "0.1.5", diff --git a/packages/ember-htmlbars/lib/hooks/attribute.js b/packages/ember-htmlbars/lib/hooks/attribute.js index 0e7f869459f..9350949b3b5 100644 --- a/packages/ember-htmlbars/lib/hooks/attribute.js +++ b/packages/ember-htmlbars/lib/hooks/attribute.js @@ -6,7 +6,7 @@ import AttrNode from "ember-views/attr_nodes/attr_node"; import EmberError from "ember-metal/error"; import { isStream } from "ember-metal/streams/utils"; -import sanitizeAttributeValue from "ember-views/system/sanitize_attribute_value"; +import sanitizeAttributeValue from "morph-attr/sanitize-attribute-value"; var boundAttributesEnabled = false; diff --git a/packages/ember-htmlbars/tests/attr_nodes/sanitized_test.js b/packages/ember-htmlbars/tests/attr_nodes/sanitized_test.js index eb2dfb6ae9b..fac34821abf 100644 --- a/packages/ember-htmlbars/tests/attr_nodes/sanitized_test.js +++ b/packages/ember-htmlbars/tests/attr_nodes/sanitized_test.js @@ -16,24 +16,39 @@ QUnit.module("ember-htmlbars: sanitized attribute", { if (Ember.FEATURES.isEnabled('ember-htmlbars-attribute-syntax')) { // jscs:disable validateIndentation +// jscs:disable disallowTrailingWhitespace var badTags = [ { tag: 'a', attr: 'href', unquotedTemplate: compile(""), quotedTemplate: compile(""), multipartTemplate: compile("") }, + + { tag: 'base', attr: 'href', + unquotedTemplate: compile(""), + quotedTemplate: compile(""), + multipartTemplate: compile("") }, + + { tag: 'embed', attr: 'src', + unquotedTemplate: compile(""), + quotedTemplate: compile(""), + multipartTemplate: compile("") }, + { tag: 'body', attr: 'background', unquotedTemplate: compile(""), quotedTemplate: compile(""), multipartTemplate: compile("") }, + { tag: 'link', attr: 'href', unquotedTemplate: compile(""), quotedTemplate: compile(""), multipartTemplate: compile("") }, + { tag: 'img', attr: 'src', unquotedTemplate: compile(""), quotedTemplate: compile(""), multipartTemplate: compile("") }, + { tag: 'iframe', attr: 'src', // Setting an iframe with a bad protocol results in the browser // being redirected. in IE8. Skip the iframe tests on that platform. diff --git a/packages/ember-views/lib/system/sanitize_attribute_value.js b/packages/ember-views/lib/system/sanitize_attribute_value.js deleted file mode 100644 index a84b93fb93d..00000000000 --- a/packages/ember-views/lib/system/sanitize_attribute_value.js +++ /dev/null @@ -1,55 +0,0 @@ -/* jshint scripturl:true */ - -var badProtocols = { - 'javascript:': true, - 'vbscript:': true -}; - -var badTags = { - 'A': true, - 'BODY': true, - 'LINK': true, - 'IMG': true, - 'IFRAME': true -}; - -export var badAttributes = { - 'href': true, - 'src': true, - 'background': true -}; - -export default function sanitizeAttributeValue(dom, element, attribute, value) { - var tagName; - - if (!element) { - tagName = null; - } else { - tagName = element.tagName; - } - - if (value && value.toHTML) { - return value.toHTML(); - } - - if ((tagName === null || badTags[tagName]) && badAttributes[attribute]) { - // Previously, we relied on creating a new `` element and setting - // its `href` in order to get the DOM to parse and extract its protocol. - // Naive approaches to URL parsing are susceptible to all sorts of XSS - // attacks. - // - // However, this approach does not work in environments without a DOM, - // such as Node & FastBoot. We have extracted the logic for parsing to - // the DOM helper, so that in locations without DOM, we can substitute - // our own robust URL parsing. - // - // This will also allow us to use the new `URL` API in browsers that - // support it, and skip the process of creating an element entirely. - var protocol = dom.protocolForURL(value); - if (badProtocols[protocol] === true) { - return 'unsafe:' + value; - } - } - - return value; -} diff --git a/packages/ember-views/tests/system/sanitize_attribute_value_test.js b/packages/ember-views/tests/system/sanitize_attribute_value_test.js deleted file mode 100644 index 7bdba562bff..00000000000 --- a/packages/ember-views/tests/system/sanitize_attribute_value_test.js +++ /dev/null @@ -1,56 +0,0 @@ -import sanitizeAttributeValue from "ember-views/system/sanitize_attribute_value"; -import { SafeString } from "ember-htmlbars/utils/string"; -import DOMHelper from "dom-helper"; - -QUnit.module('ember-views: sanitizeAttributeValue(null, "href")'); - -var goodProtocols = ['https', 'http', 'ftp', 'tel', 'file']; -var dom = new DOMHelper(); - -for (var i = 0, l = goodProtocols.length; i < l; i++) { - buildProtocolTest(goodProtocols[i]); -} - -function buildProtocolTest(protocol) { - QUnit.test('allows ' + protocol + ' protocol when element is not provided', function() { - expect(1); - - var expected = protocol + '://foo.com'; - var actual = sanitizeAttributeValue(dom, null, 'href', expected); - - equal(actual, expected, 'protocol not escaped'); - }); -} - -QUnit.test('blocks javascript: protocol', function() { - /* jshint scripturl:true */ - - expect(1); - - var expected = 'javascript:alert("foo")'; - var actual = sanitizeAttributeValue(dom, null, 'href', expected); - - equal(actual, 'unsafe:' + expected, 'protocol escaped'); -}); - -QUnit.test('blocks blacklisted protocols', function() { - /* jshint scripturl:true */ - - expect(1); - - var expected = 'javascript:alert("foo")'; - var actual = sanitizeAttributeValue(dom, null, 'href', expected); - - equal(actual, 'unsafe:' + expected, 'protocol escaped'); -}); - -QUnit.test('does not block SafeStrings', function() { - /* jshint scripturl:true */ - - expect(1); - - var expected = 'javascript:alert("foo")'; - var actual = sanitizeAttributeValue(dom, null, 'href', new SafeString(expected)); - - equal(actual, expected, 'protocol unescaped'); -});