2

最新のバックボーンとアンダースコアライブラリ(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>"}));

の期待される結果が得られます

&lt;script&gt;bad&lt;&#x2F;script&gt;

そのため、どこかでコンテンツがエスケープされなくなります。誰かがどこで、あるいはもっと良いことに、それを防ぐ方法を知っているなら、私は最も感謝するでしょう。

スティーブン


アップデート:

理解した!問題はコンソール自体ではありませんが、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"));
4

1 に答える 1

3

私はあなたのコンソールが過度に「役に立ち」、あなたを混乱させていると思います。物事をよく見ると、ここでどのような種類のチカニーが行われているのかが正確にわかります。jsfiddleの混乱を避けるために、細かく分割する必要がないようにするの<b>ではなく、に切り替えます。<script><script>

このことを考慮:

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: "<b>bad</b>"});
v = new V({model: m});
v.render();

$('body').append(v.el);
$('body').append($(v.el).text()).append('<br>');
$('body').append($(v.el).html());

このページには次の3つの内容が表示されます。

  1. リテラル<b>bad</b>
  2. bad太字のA。
  3. リテラル<b>bad</b>

それはまさに、attrエスケープされているかどうかを確認するために期待することです。

ただし、あなたはコンソールを見ています。それでは、コンソールも見て、上記のJavaScriptの下部にいくつかのことを投げてみましょう。

console.log(v.el);
console.log(v.el.innerHTML);

これで、コンソールに次のように表示されます。

<div><b>bad</b></div>
&lt;b&gt;bad&lt;/b&gt;

ただし、最初の行をよく見ると、が黒(またはコンソールがプレーンテキストに使用しているもの)であるのに対し、は紫(またはコンソールがDOM要素に使用しているハイライトカラー)で表示され<div>ているはずです。したがって、は適切にエスケープされていますが、コンソールは表示する前にデコードしています。</div><b>bad</b>attr

デモ: http: //jsfiddle.net/ambiguous/5nYTd/

于 2013-03-20T20:25:40.820 に答える