Kaçışlama
Ham HTML, backtick blokları, raw() ve kaçışlamanın çözmediği iki durum.
Backtick blokları ve raw() ham HTML üretir; diğer her değer kaçışlanır.
$doc.body.add(`<p>merhaba</p>`) # etiket olarak çıkar
$doc.body.add("<script>alert(1)</script>") # metin olarak çıkarHam işaret şu üç yerde korunur:
`<li>` + $ad + `</li>` # birleştirme: sonuç ham, $ad kaçışlanır
`<li>`$ad`</li>` # interpolasyon: aynısıfunc f() as string # anotasyon ham işareti düşürmez
return `<a href="/">x</a>`
end funcDışarıdan gelen veri#
Şablona giren her değer zaten kaçışlanır — veritabanı satırı, form alanı, query string, hepsi. Ayrıca bir şey yazmanız gerekmez:
`<td>` + $row.id + `</td>`Kaçışlama tırnakları da kapsar (", '), böylece değer bir öznitelik değerinin içine girdiğinde tırnağı kapatıp yeni bir öznitelik ekleyemez:
`<a href="` + $url + `">` # $url tırnaktan çıkamazBu sayede HTML döndüren yardımcı fonksiyonlar yazılabilir:
func ana_sayfa_bagi() as string
return `<a href="/" class="btn">Ana Sayfa</a>`
end func
$doc.body.add(`<div class="kap">` + ana_sayfa_bagi() + `</div>`)join de aynı kuralı izler: parçalardan biri ham HTML olduğunda sonuç ham HTML olur, araya giren veriler kaçışlanır.
raw()#
raw() bunun tersini yapar: kaçışlamayı kapatır. Yalnızca kendi ürettiğiniz HTML için kullanın.
`<td>` + raw($row.id) + `</td>` # YANLIŞ: veritabanındaki <script> çalışırPratikte raw() bir uygulamada tek bir yerde geçmelidir: kendi ürettiğiniz işaretlemeyi belgeye eklerken. Bütün görünüm fonksiyonları düz metin döndürüp yalnızca son adımda raw() çağrılırsa, "bu değer nereden geldi" sorusunun yanıtı tek bir satırda durur.
Kaçışlamanın çözmediği iki durum#
Bunlara kendiniz dikkat etmeniz gerekiyor.
URL şeması. href=" + $url + " içinde $url javascript:... ise kaçışlama bunu engellemez — değer zaten tırnaktan çıkmıyor, ama tarayıcı şemayı çalıştırıyor. Adresin /, #, https:// ya da mailto: ile başladığını doğrulayın:
func guvenli_url($url as string) as bool
if $url.starts_with("/") then: return true: end if
if $url.starts_with("#") then: return true: end if
if $url.starts_with("https://") then: return true: end if
if $url.starts_with("http://") then: return true: end if
if $url.starts_with("mailto:") then: return true: end if
return false
end funcTırnaksız öznitelik. href= + $url yazarsanız değerdeki bir boşluk yeni bir öznitelik başlatır. Öznitelik değerlerini her zaman tırnak içine alın.
Girdi tarafında temizleme yok#
Bu bilinçli bir karar. Girdiyi kaydederken temizlemek yaygın ama yanlış bir alışkanlıktır:
- Aynı veri başka bir bağlama gittiğinde (JSON, öznitelik, JavaScript) HTML'e göre yapılmış temizlik çalışmaz.
- Veritabanında bozulmuş metin kalır; kullanıcının yazdığı
<karakteri geri alınamaz.
Kaçışlama çıktı tarafında, yani verinin hangi bağlama girdiğinin bilindiği yerde yapılır.