最新のバックボーンとアンダースコアライブラリ(1.0.0 / 1.4.4)を使用すると、テンプレートが期待どおりにエスケープされない理由がわかりません。簡略化したバージョンは次のとおりです。
M = Backbone.Model.extend({});
V = Backbone.View.extend({
template: _.template("<%- attr %>"),
render: function() {
this.$el.html(this.template(this.model.attributes));
return this;
}
});
m = new M({attr: "<script>bad</script>"});
v = new V({model: m});
v.render();
console.log(v.el);
結果:
<div><script>bad</script></div>
明らかに、これは逃げられません。スタンドアロンコードとして実行されたテンプレートが正しくエスケープされることを確認しました。
T = _.template("<%- attr %>");
console.log(T({attr: "<script>bad</script>"}));
の期待される結果が得られます
<script>bad</script>
そのため、どこかでコンテンツがエスケープされなくなります。誰かがどこで、あるいはもっと良いことに、それを防ぐ方法を知っているなら、私は最も感謝するでしょう。
スティーブン
アップデート:
理解した!問題はコンソール自体ではありませんが、muの答えは私を正しい方向に向けました。説明するために、私のコンテキストをより正確に反映するために、上記のサンプルコードについて少し詳しく説明する必要があります。そのコンテキストは実際にはコンソール出力ではなく、単体テストです。コードがXSS攻撃から正しく保護されていることを確認したいので、単体テストを作成しました(mocha / sinon / chai / shouldを使用)。
v.$el.text().should.equal(m.escape("attr"));
次のテストが合格している間(そして私はそれがそうであるべきだとは思わなかった)、そのテストは(予期せずに)失敗していました:
v.$el.text().should.equal(m.get("attr"));
toString()
犯人は、要素オブジェクトのメソッドであることが判明しました。を使用するこのメソッドはconsole.log()
、コンテンツのエスケープを解除します。このメソッドは、関数内のjQueryでも(間接的に)使用されtext()
ます。
これがすべてのブラウザで普遍的であるかどうかはわかりませんが、私の場合、使用することでエスケープを.innerHTML()
回避できます。toString()
だから私のテストを書く正しい方法は
v.el.innerHTML().should.equal(m.escape("attr"));