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');
-});