Instantly share code, notes, and snippets.

Embed
What would you like to do?
Ember and XSS Safety

TL;DR

In Ember, always use {{...}}, not {{{...}}}. Use Ember.String.htmlSafe as necessary in JavaScript (usually in a component) to mark markup as HTML-safe. Never pass user-entered content directly to Ember.String.htmlSafe.

Details

Ember has great XSS protection built in. The HTMLBars templating library will automatically run any interpolations through htmlEscape for you. So

Hello, {{user.name}}

is protected against XSS.

But sometimes you need to get around the escaping, say if a component has built up a string that contains markup or you have an API that returns HTML fragments. Ember provides two ways of doing this. The first is to change the double-stache to triple and do any escaping in JavaScript:

Hello, {{{userNameWithMarkup}}}
userNameWithMarkup: Ember.computed('user.name', function() {
  return '<b class="user-name">' + Ember.Handlebars.Utils.escapeExpression(this.get('user.name')) + '</b>';
})

The other way to do it is to keep using double-stache, but mark the string as safe in JavaScript:

Hello, {{userNameWithMarkup}}
userNameWithMarkup: Ember.computed('user.name', function() {
  return Ember.String.htmlSafe('<b class="user-name">' + this.get('user.name') + '</b>');
})

The second is always safer than the first. The reason is that in the first case, someone else might reuse that template without properly escaping the input. In the second, if they reuse it and forget to mark a string as HTML-safe, you'll end up with over-escaped HTML, which is a bug, but not a security bug.

Of course, you should never call Ember.String.htmlSafe with user-entered content!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment