Menu

PHP htmlspecialchars(): HTML Kaçışlama ve XSS Önleme

htmlspecialchars($text) HTML'de anlam taşıyan beş karakteri (& < > " ') varlıklara çevirir, böylece kullanıcı girdisi işaretleme olarak çalışmak yerine metin olarak gösterilir. ENT_QUOTES, özniteliklerde kaçışlama, çift kodlama, htmlentities ve strip_tags konularını öğrenin.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

htmlspecialchars($text) &, <, >, " ve ' karakterlerini &amp;, &lt;, &gt;, &quot; ve &#039; değerlerine çevirir. Bir sayfaya yazdırdığınız her kullanıcı girdisi parçasında onu çağırın; girdi HTML olarak okunmak yerine metin olarak gösterilir.

Blok aynı yorumu iki kez yazdırır, bir kez ham ve bir kez kaçışlanmış. Çalıştırın ve Page sekmesindeki iki satırı karşılaştırın, sonra forma kendi HTML'inizi yazın, örneğin <h1>big</h1> veya <img src=x>, ve Show düğmesine basın.

Ham satırda tarayıcı etiketlere uyar: kalın kelime kalın olur ve <script> yazan bir ziyaretçinin betiği diğer her okuyucunun tarayıcısında çalışır. Bu saldırıya siteler arası betik çalıştırma (XSS) denir. Kaçışlanmış satırda aynı karakterler &lt;b&gt; olarak gelir ve tarayıcı onları metin olarak çizer. PHP'nin gerçekte yazdırdığı varlıkları görmek için Output sekmesine geçin.

htmlspecialchars neleri dönüştürür

Beş karakter, başka hiçbir şey. Harfler, aksanlar ve emoji değişmeden geçer.

& listededir çünkü her varlık onunla başlar: dokunulmadan bırakılsaydı &lt; ifadesinden bahseden bir yorum < olarak gösterilirdi.

Yalnızca metni değil, öznitelikleri de kaçışlayın

Bir özniteliğin içindeki kullanıcı girdisi de aynı ölçüde kaçışlama gerektirir. O olmadan değerdeki bir tırnak özniteliği kapatır ve girdinin geri kalanı yeni öznitelikler olur. Burada "isim" gizlice bir style özniteliği ekler; çalıştırın ve iki kutuya bakın.

Güvensiz kutuda tarayıcı value="Ada" ve ardından yeni bir style özniteliği görür, bu yüzden kutu kırmızıya döner ve yalnızca Ada gösterir. Bir saldırgan orada style yerine onfocus="..." yazardı ve kodu çalışırdı. Güvenli kutuda her " &quot; oldu, bu yüzden dizgenin tamamı value içinde kalır ve yazıldığı gibi gösterilir.

PHP 8.1'den beri varsayılan bayraklar ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 olduğu için tek tırnaklar da kaçışlanır ve '...' ile yazılan öznitelikler güvenlidir. Eski kodlar çoğu zaman ENT_QUOTES değerini elle verir ve PHP 7 ve öncesinde bu gerekliydi:

Şablonlar için kısa bir yardımcı

Bir şablonda düzinelerce kez htmlspecialchars($x, ENT_QUOTES, 'UTF-8') yazmak kalabalık yaratır, bu yüzden çoğu proje onu tek harfli bir fonksiyonla sarar. Twig ve Blade gibi şablon motorları her {{ $var }} için aynısını otomatik olarak yapar.

?string türü ve ?? '' önemlidir: htmlspecialchars() fonksiyonuna null vermek PHP 8.1'den beri kullanımdan kaldırılmıştır ve sizin PHP'niz biyografisi olmayan her kullanıcı için bir kullanımdan kaldırma bildirimi yazdırırdı.

Çift kodlama ve htmlspecialchars_decode

Bir değer iki kez kaçışlanırsa okuyucu varlıkları görür: & ilk seferde &amp;, ikincisinde &amp;amp; olur ve tarayıcı bunu &amp; olarak gösterir. Bu genellikle değerin kaydedilirken ve yazdırılırken yeniden kaçışlandığı anlamına gelir. Var olan varlıklara dokunmamak için double_encode: false verin ve geri dönmek için htmlspecialchars_decode() kullanın.

Gerçek çözüm ham metni saklamak ve yalnızca çıktıda kaçışlamaktır. double_encode: false içe aktarılmış bir besleme gibi sizin oluşturmadığınız varlıklar içeren metinler içindir.

htmlspecialchars, htmlentities ve strip_tags karşılaştırması

Bu üçü sık karıştırılır. Blok hepsini aynı girdi üzerinde çalıştırır ve her biri için PHP'nin ne yazdırdığını ve tarayıcının bundan ne çıkardığını gösterir:

  • htmlspecialchars() beş HTML karakterini kaçışlar. HTML'e yazdırdığınız her metin için kullanın.
  • htmlentities() ayrıca é karakterini &eacute; yapar. Sayfalar UTF-8 değilken kullanışlıydı; bugün yalnızca kaynağı okumayı zorlaştırır.
  • strip_tags() etiketleri siler ve metinlerini korur. HTML'i düz metne çevirmek (bir e-posta önizlemesi, bir meta açıklama) içindir, güvenlik için değil: son satır izin verilen bir <b> etiketinin onclick özniteliğini koruduğunu ve bir özniteliğin içine konan metne hiç dokunulmadığını gösterir.

htmlspecialchars'ın yetmediği yerler

htmlspecialchars() HTML metni ve tırnaklı öznitelikler için doğru kaçışlamadır. Bir sayfanın diğer yerlerinin başka kuralları vardır:

  • Bir URL'de http_build_query() veya urlencode() değeri kodlar; htmlspecialchars() ardından parametreler arasındaki & işaretini geçerli HTML yapar.
  • JavaScript'te json_encode() geçerli bir JS değeri üretir ve JSON_HEX_TAG < ve > karakterlerini \u003C ve \u003E yapar, böylece verideki bir </script> betik etiketini kapatamaz.
  • Kullanıcı girdisini şemasını kontrol etmeden asla bir href içine yazdırmayın: htmlspecialchars('javascript:alert(1)') değişmez ve tıklandığında yine çalışır. filter_var sayfasında gösterildiği gibi yalnızca http ve https URL'lerini kabul edin.

Bunların hepsini bir araya getiren form işleme için PHP formlar sayfasına bakın.

Sıkça Sorulan Sorular

PHP'de htmlspecialchars ne işe yarar?

&, <, >, " ve ' karakterlerini &amp;, &lt;, &gt;, &quot; ve &#039; ile değiştirir. Tarayıcı o zaman bu karakterleri HTML olarak okumak yerine gösterir, böylece bir forma yazılan <script> metin olarak gösterilir ve asla çalışmaz.

htmlspecialchars ile htmlentities arasındaki fark nedir?

htmlspecialchars() yalnızca HTML'de özel olan beş karakteri dönüştürür. htmlentities() adlandırılmış bir varlığı olan her karakteri de dönüştürür, bu yüzden café caf&eacute; olur. UTF-8 sayfalarda ikisi de eşit derecede güvenlidir ve htmlspecialchars() çıktıyı okunur tuttuğu için olağan seçimdir.

PHP 8'de hâlâ ENT_QUOTES gerekiyor mu?

Güvenlik için değil: PHP 8.1'den beri varsayılan bayraklar ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 olduğu için tek tırnaklar da kaçışlanır. Birçok kod tabanı, çağrının eski sürümlerde de aynı davranması ve okuyucular için açık olması için ENT_QUOTES, 'UTF-8' değerini hâlâ açıkça verir.

htmlspecialchars girdide mi yoksa çıktıda mı kullanılmalı?

Çıktıda. Ham değeri saklayın ve doğrulayın, onu HTML'e yazdırdığınız anda kaçışlayın. Girdide kaçışlamak veritabanınızda &lt; saklar, uzunlukları ve aramaları bozar ve &amp;lt; gibi çift kaçışlamaya yol açar.

strip_tags XSS'i önlemek için yeterli mi?

Hayır. strip_tags() etiketleri siler ama izin verilen etiketler parametresi onların özniteliklerini korur, bu yüzden <b onclick="..."> hayatta kalır ve bir özniteliğin içine konan metin için hiçbir şey yapmaz. Kullanıcı girdisini yazdırırken htmlspecialchars() kullanın.

Coddy programlama dilleri çizimi

Coddy ile kodlamayı öğren

BAŞLA