2010-11-01 7 views
9
O html_safe gibi hissediyor

örneğin, ne olup bittiğini anlamayı gerektirir String sınıfına bir soyutlama, söylediğimiz eğerNeden Rails 3, <% = note.html_safe%> ve <% = h note.html_safe%> aynı sonucu veriyor?

4. satırda için
<%= '1 <b>2</b>' %>  # gives 1 &lt;b&gt;2&lt;/b&gt; in the HTML source code 

<%= h '1 <b>2</b>' %> # exactly the same as above 

<%= '1 <b>2</b>'.html_safe %>  # 1 <b>2</b> in HTML source code 

<%= h '1 <b>2</b>'.html_safe %> # exactly the same as above 

<%= h (h '1 <b>2</b>') %> # 1 &lt;b&gt;2&lt;/b&gt; wont' escape twice 

, tamam, biz dize güven ekler - bu Güvende, ama neden kaçamıyoruz? h ile kaçmak için, dizinin güvensiz olması gerektiği görünüyor. dize h tarafından kaçmış değilse Yani 1. satırda

, otomatik olarak atlanır. 5 satırında h iki kez dize kaçamaz - diğer bir deyişle, <&lt; değiştirildiğinde sonra, o &amp;lt; bir kez daha kaçamaz.

Yani ne oluyor? İlk başta, html_safe sadece güvenli olduğunu söyleyerek dizgiye bir bayrağı etiketlediğini düşündüm. Öyleyse, neden h bundan kaçmıyor? ne zaman dize sonra,

1) bir dize html_safe ise, h o

2 kaçamayacak) bir dize html_safe değilse: h ve html_escape aslında bayrağını kullanma konusunda işbirliği gibi görünüyor çıktı arabelleğine eklenir, h tarafından otomatik olarak çıkarılacaktır.

3) h zaten bir dize kaçtıysa, html_safe işaretlenir ve bu nedenle, h tarafından bir kez daha sızmak herhangi bir etki yapmayacaktır. Bu davranış bile Raylar 2.3.10 aynıdır, ama Ruby on 2.3.5 h aslında çok Raylar 2.3.5 yılında ... iki kez kaçabilir Hat 5 olduğu gibi, ve (, h basit bir kaçış yöntemidir, ancak bazı nerede 2.3.10 hat boyunca, h kadar basit değil oldu. ama 2.3.10 oto bir dize kaçış olmaz, ancak bazı nedenlerden dolayı, yöntem html_safe zaten 2.3.10 için var (hangi amaçla?))

Tam olarak böyle mi çalışıyor? Bence günümüzde bazen çıktıda istediğimiz şeyi alamıyoruz ve değişkenimize html_safe'u ekliyoruz, ki bu oldukça tehlikeli olabilir, çünkü XSS saldırısını bu şekilde sunabilir, bu yüzden tam olarak nasıl çalıştığını anlamak oldukça önemli olabilir . Yukarıdakiler tam olarak nasıl çalıştığının bir tahmindir. Aslında farklı bir mekanizma olabilir ve bunu destekleyen herhangi bir belge var mı?

cevap

6

Gördüğünüz gibi, bir ipe html_safe çağıran()

saat boyunca geçilecek SafeBuffer

http://github.com/rails/rails/blob/89978f10afbad3f856e2959a811bed1982715408/activesupport/lib/active_support/core_ext/string/output_safety.rb#L87

dize güvenliğini etkileyebilecek bir SafeBuffer üzerindeki herhangi işlemleri güvenli bir html haline döner

saat kaçan çift önlemek için bu bayrak kullanır

http://github.com/rails/rails/blob/89978f10afbad3f856e2959a811bed1982715408/activesupport/lib/active_support/core_ext/string/output_safety.rb#L18

Davranış değişti ve bence nasıl çalıştığına dair çoğunlukla doğru. Genelde, html_safe'yi halihazırda sterilize edilmediğinden emin değilseniz çağırmamalısınız.şey gibi, tüm çıkış varsayılan olarak h yardımcı kullanıyor, raylar 3'te o

+1

ilginç ... "flag" olarak yeni bir class SafeBuffer kullanıyor ... bu yüzden "foobar" .html_safe "aslında orijinal dizinin içeriği ile yeni bir SafeBuffer örneği oluşturacak ve döndürecek ... –