İçeriğe geç
LexerLangv0.1.0

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.

LexerLang
$doc.body.add(`<p>merhaba</p>`)             # etiket olarak çıkar
$doc.body.add("<script>alert(1)</script>")  # metin olarak çıkar

Ham işaret şu üç yerde korunur:

LexerLang
`<li>` + $ad + `</li>`        # birleştirme: sonuç ham, $ad kaçışlanır
`<li>`$ad`</li>`              # interpolasyon: aynısı
LexerLang
func f() as string            # anotasyon ham işareti düşürmez
    return `<a href="/">x</a>`
end func

Dış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:

LexerLang
`<td>` + $row.id + `</td>`

Kaçışlama tırnakları da kapsar (&#34;, &#39;), böylece değer bir öznitelik değerinin içine girdiğinde tırnağı kapatıp yeni bir öznitelik ekleyemez:

LexerLang
`<a href="` + $url + `">`      # $url tırnaktan çıkamaz

Bu sayede HTML döndüren yardımcı fonksiyonlar yazılabilir:

LexerLang
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.

LexerLang
`<td>` + raw($row.id) + `</td>`    # YANLIŞ: veritabanındaki <script> çalışır

Pratikte 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:

LexerLang
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 func

Tı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.

Sırada#

Şifreleme.