diff --git a/packages/ember-htmlbars/tests/attr_nodes/style_test.js b/packages/ember-htmlbars/tests/attr_nodes/style_test.js new file mode 100644 index 00000000000..d40540edcad --- /dev/null +++ b/packages/ember-htmlbars/tests/attr_nodes/style_test.js @@ -0,0 +1,51 @@ +import EmberView from "ember-views/views/view"; +import compile from "ember-template-compiler/system/compile"; +import { SafeString } from "ember-htmlbars/utils/string"; +import { runAppend, runDestroy } from "ember-runtime/tests/utils"; + +var view; + +QUnit.module("ember-htmlbars: style attribute", { + teardown() { + runDestroy(view); + } +}); + +if (Ember.FEATURES.isEnabled('ember-htmlbars-attribute-syntax')) { +// jscs:disable validateIndentation + +QUnit.test('specifying `
') + }); + + expectDeprecation(function() { + runAppend(view); + }, /Dynamic content in the `style` attribute is not escaped and may pose a security risk. Please preform a security audit and once verified change from `
` to `
/); +}); + +QUnit.test('specifying `
') + }); + + expectNoDeprecation(function() { + runAppend(view); + }); +}); + +QUnit.test('specifying `
') + }); + + expectNoDeprecation(function() { + runAppend(view); + }); +}); + +// jscs:enable validateIndentation +} diff --git a/packages/ember-htmlbars/tests/helpers/bind_attr_test.js b/packages/ember-htmlbars/tests/helpers/bind_attr_test.js index d180ba6980c..258de306108 100644 --- a/packages/ember-htmlbars/tests/helpers/bind_attr_test.js +++ b/packages/ember-htmlbars/tests/helpers/bind_attr_test.js @@ -599,3 +599,25 @@ QUnit.test("src attribute bound to null is not present", function() { ok(!view.element.hasAttribute('src'), "src attribute not present"); }); + +QUnit.test('specifying `
` is [DEPRECATED]', function() { + view = EmberView.create({ + userValue: '42', + template: compile('
') + }); + + expectDeprecation(function() { + runAppend(view); + }, /Dynamic content in the `style` attribute is not escaped and may pose a security risk. Please preform a security audit and once verified change from `
` to `
/); +}); + +QUnit.test('specifying `
` works properly', function() { + view = EmberView.create({ + userValue: '42', + template: compile('
') + }); + + expectNoDeprecation(function() { + runAppend(view); + }); +}); diff --git a/packages/ember-views/lib/attr_nodes/attr_node.js b/packages/ember-views/lib/attr_nodes/attr_node.js index b2892a5babf..faf328cad19 100644 --- a/packages/ember-views/lib/attr_nodes/attr_node.js +++ b/packages/ember-views/lib/attr_nodes/attr_node.js @@ -3,6 +3,7 @@ @submodule ember-htmlbars */ +import Ember from 'ember-metal/core'; import { read, subscribe, @@ -26,6 +27,8 @@ AttrNode.prototype.init = function init(attrName, simpleAttrValue) { this.isDestroying = false; this.lastValue = null; this.hasRenderedInitially = false; + this._dynamicStyleDeprecationMessage = '`
` to ' + + '`
`.'; subscribe(this.attrValue, this.rerender, this); }; @@ -59,12 +62,28 @@ AttrNode.prototype.render = function render(buffer) { } if (this.lastValue !== null || value !== null) { + this._deprecateEscapedStyle(value); this._morph.setContent(value); this.lastValue = value; this.hasRenderedInitially = true; } }; +AttrNode.prototype._deprecateEscapedStyle = function AttrNode_deprecateEscapedStyle(value) { + Ember.deprecate( + 'Dynamic content in the `style` attribute is not escaped and may pose a security risk. ' + + 'Please preform a security audit and once verified change from ' + + this._dynamicStyleDeprecationMessage, + (function(name, value, escaped) { + // SafeString + if (value && value.toHTML) { + return true; + } + return name !== 'style' || !escaped; + }(this.attrName, value, this._morph.escaped)) + ); +}; + AttrNode.prototype.rerender = function render() { this.isDirty = true; run.schedule('render', this, this.renderIfDirty); diff --git a/packages/ember-views/lib/attr_nodes/legacy_bind.js b/packages/ember-views/lib/attr_nodes/legacy_bind.js index dd2ebcceeff..cda3fe51176 100644 --- a/packages/ember-views/lib/attr_nodes/legacy_bind.js +++ b/packages/ember-views/lib/attr_nodes/legacy_bind.js @@ -11,6 +11,9 @@ import o_create from "ember-metal/platform/create"; function LegacyBindAttrNode(attrName, attrValue) { this.init(attrName, attrValue); + + this._dynamicStyleDeprecationMessage = '`
` to ' + + '`
`.'; } LegacyBindAttrNode.prototype = o_create(AttrNode.prototype); @@ -34,6 +37,7 @@ LegacyBindAttrNode.prototype.render = function render(buffer) { value === null || value === undefined || typeOf(value) === 'number' || typeOf(value) === 'string' || typeOf(value) === 'boolean'); if (this.lastValue !== null || value !== null) { + this._deprecateEscapedStyle(value); this._morph.setContent(value); this.lastValue = value; }