Mehmet

WFN Üye
Konular
1,851
Mesajlar
1,852
Çözüm
0
Ticaret Puanı
0
Üyelik
1 Ay 7 Gün
Konum
YurtDışı
Web Sitesi
Var
Alanı
Google Adsense
1/1
Konu sahibi
HTML çıktı kodlaması, verinin sayfada kullanılacağı bağlama göre yapılmalıdır. HTML metin düğümüne yazılan değer HTML bağlamına, etiket niteliğine yazılan değer nitelik bağlamına, JavaScript içine aktarılan değer JavaScript bağlamına göre kodlanır. Her yerde aynı kaçış yöntemini kullanmak güvenli ve doğru değildir; HTML için kullanılan kodlama JavaScript veya URL içinde yeterli olmayabilir.

Bağlama göre kodlama nasıl çalışır?​


Kullanıcıdan, veritabanından veya başka bir servisten gelen değer güvenilir kabul edilmemelidir. Değer, sayfaya eklenmeden hemen önce ve hedef bağlam bilinerek kodlanır. Veriyi girişte HTML entity'lerine çevirmek yerine ham biçimde saklamak, gerektiğinde farklı ortamlarda yeniden kullanmayı kolaylaştırır.

Örneğin kullanıcı adı şu değer olsun:
"><script>alert(1)</script>

Bu değer HTML metni olarak gösterilecekse özel karakterler entity biçimine çevrilmelidir. PHP ile küçük bir örnek:
Kod:
<?php
$kullaniciAdi = '"><script>alert(1)</script>';
?>
<!doctype html>
<html lang="tr">
<head><meta charset="utf-8"><title>Profil</title></head>
<body>
<p>Kullanıcı: <?= htmlspecialchars($kullaniciAdi, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?></p>
</body>
</html>

Beklenen sonuç, betiğin çalışması değil, karakterlerin metin olarak görünmesidir. Değer sayfada çalışabilir kod hâline geliyorsa ya yanlış bağlam kodlaması kullanılmıştır ya da kodlanmamış başka bir çıktı noktası kalmıştır. ENT_SUBSTITUTE geçersiz UTF-8 dizilerinin çıktıyı bozmak yerine değiştirilmesini sağlar; uygulamanın kullandığı karakter kümesiyle kodlama parametresi aynı olmalıdır.

Yaygın çıktı bağlamları​


Aşağıdaki ayrım, hangi yöntemin seçileceğini belirler:

BağlamDoğru yaklaşımKaçınılması gereken
HTML metniHTML özel karakterlerini encode etmekHam kullanıcı verisini doğrudan yazmak
HTML niteliğiTırnakları da kapsayan HTML attribute encodingNiteliği tırnaksız bırakmak
JavaScript verisiÇevre bağlamı güvenli serileştirme; mümkünse ayrı JSON yanıtıDeğeri JavaScript metniyle birleştirmek
CSS değeriİzin verilen değerleri listeyle sınırlamakKullanıcı metnini CSS kodu gibi eklemek
URL parametresiURL bileşenine uygun percent-encodingHTML encode etmeyi URL encode sanmak

Tablodaki yöntemler birbirinin yerine geçmez. Örneğin URL parametresi için HTML entity kodlamak, URL'nin doğru oluşturulduğu anlamına gelmez. URL daha sonra HTML niteliğine yerleştiriliyorsa önce URL bileşeni, ardından dış HTML niteliği için gereken işlem uygulanmalıdır; daha basit ve güvenli seçenek, URL'yi elle birleştirmek yerine platformun URL oluşturma API'sini kullanmaktır.

Uygulama adımları​


  1. Değerin kaynağını ve hedefini belirleyin: HTML metni, attribute, inline JavaScript, CSS veya URL. Aynı değişkenin farklı hedeflerde kullanıldığı yerleri ayrı ayrı inceleyin.
  2. Metni mümkünse textContent ile yerleştirin. setAttribute yalnız sabit ve güvenli nitelik adlarıyla kullanılmalıdır; onclick gibi olay niteliği veya href/src gibi URL alanı her değer için güvenli değildir. URL şemasını ve hedef politikasını ayrıca doğrulayın; javascript: değeri HTML escaping ile güvenli URL olmaz.
  3. Sunucu tarafı şablonunda HTML metni ve attribute değerleri için bağlama uygun HTML escaping uygulayın. Attribute değerlerini daima tırnak içinde üretin.
  4. JavaScript'e veri geçirmek zorundaysanız değeri JavaScript kaynak kodu olarak birleştirmeyin; ayrı application/json yanıtı gibi veri taşıma yöntemini tercih edin. Inline script içine JSON gömülüyorsa düz JSON.stringify/json_encode çıktısını yeterli sanmayın; HTML script kapanışı gibi çevre bağlamı da güvenli serileştirilmelidir. PHP’de uygun JSON_HEX_TAG gibi bayraklar bu bağlam için değerlendirilebilir.
  5. İzin verilen değerleri sınırlayın. CSS sınıfı, sıralama yönü veya HTML etiketi gibi alanlarda yalnızca beklenen sabit değerleri kabul etmek, sonradan kaçış yapmaya göre daha sağlamdır.
  6. Her çıktı noktasını saldırı karakterleri içeren test değeriyle kontrol edin. Sonuç metin olarak görünmeli, yeni etiket veya komut olarak yorumlanmamalıdır.

Sık yapılan hatalar​


Girdiyi kaydederken encode etmek: Aynı veri e-posta, JSON veya rapor içinde kullanılacaksa önceden HTML'e çevrilmiş entity'ler sorun çıkarabilir. Ham veriyi uygun doğrulamayla saklayıp çıktı bağlamında kodlamak genellikle daha doğru yaklaşımdır.

HTML encode'u her yerde kullanmak: HTML metni için doğru olan yöntem JavaScript, CSS veya URL bağlamında aynı korumayı sağlamaz. Özellikle script içine string birleştirmek, HTML karakterlerini kaçırmakla güvenli hâle gelmez.

Güvenilir görünen veriyi atlamak: Veritabanı yöneticisi, yönetici hesabı veya dış servis yanıtı da değiştirilmiş olabilir. Güven kararı kaynağa göre değil, verinin kullanılacağı bağlama göre verilmelidir.

Çift kodlama yapmak: Bir değer daha önce encode edilmişse tekrar encode etmek kullanıcıya &amp; gibi metinler gösterebilir. Veri akışını izleyin; hangi katmanda dönüşüm yapıldığını netleştirin ve tek bir sorumlu çıktı katmanı belirleyin.

Sık sorulan sorular​

Şablon otomatik escape yapıyorsa raw çıktıya geçebilir miyim?​

Raw veya safe işaretleri çoğu şablon motorunda varsayılan korumayı devre dışı bırakır. Kullanıcı metnini biçimli göstermek için bunu doğrudan kullanmayın; gerekiyorsa bakım gören bir HTML temizleyiciyle açık izin listesi uygulayın. Çıktı sonradan JavaScript ile değiştirilirse hedef bağlam yeniden önem kazanır.

Veritabanındaki HTML entity değerini önce çözmeli miyim?​

Eski veri akışında önceden kodlama yapılmış olabilir; tüm veriyi koşulsuz çözmek yeni XSS yolu açabilir. Kaynağın metin mi izin verilen HTML mi olduğunu belirleyin, geçişi örneklerle sınayın ve son çıktı noktasının kodlamasını koruyun. Çift kodlamayı gidermek için korumayı topluca kapatmayın.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Konuyu görüntüleyenler

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic