4

I was doing some reading on Cross-Site Scripting (XSS) attacks today. It seems that Backbone has model.escape('attr') built in and from what I can tell that should always be used instead of model.get('attr') to prevent these attacks.

I did some initial searching but didn't find any recommendations of the sort. Should I always use model.escape('attr') when retrieving values from a model?

Brandon
  • 1,399
  • 4
  • 20
  • 37

4 Answers4

5

Using Underscore templates, I've generally seen/done it like this:

var TemplateHtml = "<div><%- someModelAttribute %></div>"; // Really, you should load from file using something like RequireJS

var View = Backbone.View.extend({
    _template: _.template(TemplateHtml),

    render: function() {
        this.$el.html(this._template(this.model.toJSON()));
    }
});

When you use <%- someModelAttribute %>, Underscore knows to escape the given values (as opposed to <%= someModelAttribute %> which injects the attribute directly without escaping).

Lukas
  • 9,765
  • 2
  • 37
  • 45
  • I think your %- and %= are the wrong way around, well according to this: http://stackoverflow.com/questions/16183748/how-to-escape-html-in-node-js-ejs-view – Richard Nov 23 '16 at 14:57
  • @Richard It's been awhile since I've used Backbone, but doesn't it use `_.template` from Underscore.js? http://underscorejs.org/#template – Lukas Dec 02 '16 at 20:58
3

Instead of model.escape(), see _.escape while rendering. So, you can use your models as you want but be careful to escape while rendering. It is enough to just use _.escape in your template while rendering. This avoids XSS attacks.

See this method:

http://underscorejs.org/#escape

GautamJeyaraman
  • 545
  • 2
  • 11
1

Yes, to aviod xss attacks you may always use model.escape() which is preferable and it is also used to escape the html contents...

But if you are going to use the data straight away... you can simplt use model.get()...

0

I found a good article on when to use the backbone escape function. The author asserts that you should always use escape, apart from when you are definitely not going to be executing the value of a model attribute. For example if you were checking a model attribute was not null:

var model = new Backbone.Model({foo: "Bar"});
if (model.get("foo") != null) { //notice how here we did not use escape
  $("h1").html(model.escape("foo")); //but here we do
}

One related point to be aware of is that if you check for the returned value from model.escape("foo") it will always return a string. So if you are expecting null then you may be confused.

console.log(model.get("foo")); // null
console.log(model.escape("foo")); // ""

However, as Jeremy Ashkenas points out in a pull report querying this issue, it does not make sense to check the existence of an attribute after escaping it.

cs_stackX
  • 1,407
  • 2
  • 19
  • 27