使用最新的主幹和下劃線庫(1.0.0/1.4.4)我找不出我的模板爲什麼不像我期望的那樣轉義。下面是一個簡化版本:Backbone.js/Underscore.js:爲什麼我的模板不能轉義
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>
預期的結果所以某處內容越來越轉義。如果有人知道在哪裏,或者更好,如何防止它,我會非常感激。
斯蒂芬
更新:
想通了!雖然問題不是控制檯本身,畝的答案確實指向了我的正確方向。爲了解釋,我需要對上面的示例代碼稍加說明,以便它更準確地反映我的上下文。該上下文實際上並不是控制檯輸出,而是單元測試。我想驗證我的代碼是否正確防範XSS攻擊,所以我寫的單元測試(採用摩卡/興農/柴/應):
v.$el.text().should.equal(m.escape("attr"));
那個測試不及格(意外),而下面測試路過(我不認爲它應該是):
v.$el.text().should.equal(m.get("attr"));
罪魁禍首原來的元素對象上是toString()
方法。該方法,即console.log()
使用的方法可以使內容失效。在text()
函數中,jQuery也(間接)使用該方法。
我不確定這在所有瀏覽器中都是通用的,但在我的情況下使用.innerHTML()
可以避免使用toString()
unescape。所以正確的方法來寫我的測試是
v.el.innerHTML().should.equal(m.escape("attr"));
http://stackoverflow.com/faq#signatures – forivall 2013-03-20 19:51:42