Özel karakterleri HTML güvenli entity kodlarına dönüştürün ve XSS açıklarına karşı kodlarınızı güvenle sanitize edin.
Web sayfaları HTML (HyperText Markup Language) etiketleriyle inşa edilir. Modern web tarayıcıları bir HTML belgesini ağ üzerinden indirip Document Object Model (DOM) ağacına dönüştürürken W3C ve WHATWG HTML Living Standard spesifikasyonlarına göre çalışan bir HTML Tokenizer ve Tree Builder ayrıştırma motoru kullanır. Bu motor, sözdizimi ayracı olarak kabul ettiği <, >, &, " ve ' gibi karakterlerle karşılaştığında yeni bir etiket açılışı veya nitelik (attribute) tanımı başlatır.
Kullanıcı kaynaklı girdiler, veritabanından çekilen dinamik veriler veya teknik dökümantasyonlar doğrudan web sayfasına yazdırıldığında, bu karakterlerin tarayıcı tarafından istem dışı çalıştırılabilir kod (script) sanılmasını önlemek ve metinsel olarak hatasız render edilmesini sağlamak için HTML Entity (Karakter Varlığı) kaçış dizilimleri kullanılır. Bir HTML entity ifadesi her zaman ampersand (&) ile başlar ve noktalı virgül (;) ile sonlanır.
< (Less-Than / U+003C)
> (Greater-Than / U+003E)
& (Ampersand / U+0026)
" (Quote / U+0022)
' (Apostrophe / U+0027)
HTML varlıkları iki ana grupta temsil edilir:
© ©, ™ ™, € € veya bölünemez boşluk). WHATWG standardı 2.200'den fazla isimlendirilmiş varlık tanımlamıştır; ancak bu isimler eski XML ayrıştırıcılar veya katı DTD doğrulayıcılar tarafından tanınmayabilir.&#[0-9]+; sözdizimiyle yazılır. Örneğin küçüktür işareti için < veya Türk Lirası sembolü için ₺.&#x[0-9a-fA-F]+; sözdizimiyle yazılır. Örneğin < veya Türk Lirası için ₺. Sayısal varlıklar XML standartlarıyla tam uyumludur ve hiçbir DTD tanımlaması gerektirmeksizin tüm cihazlarda kusursuz render edilir.OWASP (Open Web Application Security Project) XSS Savunma Kılavuzu'na göre, web uygulamalarında verinin güvenli şekilde yansıtılması (escaping) tamamen verinin DOM içerisindeki bağlamına (context) bağlıdır:
<div>...</div>): < ve & karakterlerinin entity haline getirilmesi tarayıcının yeni bir etiket açmasını engeller.<input value="...">): Tırnak işaretlerinin (" ve ') kodlanması, saldırganın nitelik sınırını kırıp onclick veya autofocus eklemesini önler.<script>let data = '...';</script>): HTML Entity kodlaması JavaScript bağlamında etkisizdir! Tarayıcının JavaScript motoru entity'leri çözmez. Bu bağlamda JSON serialization (json_encode) veya Unicode kaçışları (\u0022) kullanılmalıdır.<a href="...">): Saldırgan javascript:alert(1) protokolü enjekte edebilir. Bu bağlamda URL protokol doğrulaması ve RFC 3986 percent-encoding uygulanmalıdır.Web geliştirme ve siber güvenlik süreçlerinde kullanılan farklı dönüştürme ve sanitizasyon tekniklerinin kapsamı:
| Kodlama & Sanitizasyon Yöntemi | Standart / Spesifikasyon | Hedef Çıktı Ortamı | Güvenlik Kapsamı (Security Scope) | Karakter Dönüşüm Örneği | Tipik Kullanım Alanı |
|---|---|---|---|---|---|
| HTML Entity Encoding | W3C HTML5 / WHATWG | HTML Body & Standart Attributes | XSS & DOM Injection engelleme | <script> → <script> |
Kullanıcı yorumları, CMS makaleleri, form girişleri. |
| URL Percent-Encoding | RFC 3986 | URL Path, Query Strings & Form Data | HTTP Header & Parametre ayrıştırma | İstanbul & Ankara → %C4%B0stanbul%20%26%20Ankara |
REST API sorguları, arama parametreleri, yönlendirme linkleri. |
| Base64 Data Encoding | RFC 4648 | ASCII-Only Protokoller (E-posta, JSON) | İkili (Binary) veri bütünlüğü koruma | İkili Dosya / Resim → iVBORw0KGgoAAAANSU... |
Data URI (inline görseller), JWT token'ları, e-posta ekleri. |
| JSON Unicode Escaping | RFC 8259 / ECMA-404 | JavaScript Değişkenleri & JSON API | JS Injection & JSON parse koruması | "Metin" → \u0022Metin\u0022 |
Backend'den frontend'e veri aktarımı, REST API yanıtları. |
| HTML Sanitization (DOMPurify) | W3C DOM & Safe HTML Spec | Zengin Metin (Rich-Text HTML) | Zararlı etiket ve event temizleme | <b>Ok</b><script>...</script> → <b>Ok</b> |
WYSIWYG editör içerikleri, forum imzaları, e-posta gövdeleri. |
Senaryo & Problem: Aylık 1 milyondan fazla tekil ziyaretçisi olan bir e-ticaret platformunda, ürün detay sayfalarındaki müşteri yorumları veritabanında saklanmakta ve şablon motorunda ham çıktı (raw HTML) olarak sayfaya basılmaktadır ({!! $yorum->icerik !!}). Kötü niyetli bir kullanıcı yorum metni alanına şu zararlı payload'ı eklemiştir:
Platform yöneticisi yorumları onaylamak için yönetim paneline girdiğinde, tarayıcı <img> etiketinin resmini yükleyememiş ve onerror olay işleyicisini tetiklemiştir. Yönetici oturum çerezi (session cookie) saniyeler içinde saldırganın sunucusuna iletilmiş, e-ticaret yönetim paneli ele geçirilmiş ve 4.000'den fazla müşteri siparişi riske girmiştir.
Uygulanan Çözüm: Çok katmanlı savunma stratejisi devreye alınmıştır:
htmlspecialchars($yorum->icerik, ENT_QUOTES | ENT_HTML5, 'UTF-8') uygulanmıştır. Böylece <img> etiketi <img> haline gelerek zararsız düz metin olarak gösterilmiştir.HttpOnly; Secure; SameSite=Strict bayrakları atanarak olası XSS açıklarında dahi JavaScript'in (document.cookie) oturum anahtarına erişmesi tarayıcı seviyesinde kilitlenmiştir.Content-Security-Policy: default-src 'self'; script-src 'self' başlığı eklenerek harici alan adlarına yetkisiz veri aktarımı engellenmiştir.
Senaryo & Problem: Çok uluslu bir SaaS firmasının fatura oluşturma sistemi (Dompdf / wkhtmltopdf tabanlı) ve eski sürüm kurumsal Outlook e-posta istemcileri, UTF-8 Türk Lirası sembolünü (₺), çift tırnakları (“ ”) ve Türkçe karakterleri (ş, ğ) doğru render edememekte; faturalarda müşteri unvanları Ömer yerine Ömer, tutar haneleri ise 1.500 ₺ veya soru işareti ? şeklinde bozuk (Mojibake) çıkmaktadır. Bu durum kurumsal müşterilerin muhasebe departmanlarıyla ciddi güven krizlerine yol açmıştır.
Uygulanan Çözüm: Dinamik PDF ve HTML e-posta derleme katmanında, Unicode glifleri evrensel Sayısal Varlık (Numeric Character Reference - NCR) kodlarına dönüştürülmüştür:
Teknik Sonuç: Türk Lirası karakteri evrensel onluk kod olan ₺ (veya onaltılık ₺) ile değiştirildiğinde, yazı tipi (font-family) desteklemese dahi tarayıcı ve PDF motoru glifi doğru glif tablosundan eşleştirmiştir. Eski Outlook masaüstü uygulamalarından en güncel mobil e-posta istemcilerine kadar tüm platformlarda fatura ve teklifler %100 kusursuz görüntülenmiştir.
| Hata Tipi | Görülen Semptom & Güvenlik Riski | Hatalı / Güvensiz Kod | Doğru & Standart Yaklaşım |
|---|---|---|---|
| 1. JS Bağlamında HTML Entity | Script etiketinde HTML entity çözülmez; JavaScript sözdizimi kırılır veya XSS engellenemez. | <script>let u = '"';</script> |
<script>let u = <?= json_encode($val) ?>;</script> |
| 2. Çift Kodlama (Double Encoding) | Zaten entity olan metin tekrar kodlanır ve ekranda &lt; çirkin metinleri belirir. |
htmlspecialchars($zatenKodluMetin) |
htmlspecialchars($metin, ENT_QUOTES, 'UTF-8', false) (4. argüman $double_encode = false). |
| 3. Tek Tırnağı Atlamak (ENT_COMPAT) | PHP'de varsayılan mod eski sürümlerde tek tırnakları (') kaçırmaz; tek tırnaklı attribute'larda XSS oluşur. |
htmlspecialchars($input) (Varsayılan) |
htmlspecialchars($input, ENT_QUOTES | ENT_HTML5, 'UTF-8') |
| 4. URL ile HTML Encoding Karmaşası | URL içindeki & ayracı %26 yapılınca backend parametreyi tek parametre sanır. |
<a href="p.php?a=1%26b=2"> |
<a href="p.php?a=1&b=2"> (URL için & kalmalı, HTML için & olmalı). |
| 5. Noktalı Virgülü (;) Unutmak | © gibi noktalı virgülsüz yazımlar XML, XHTML ve modern katı parser'larda parse hatası verir. |
© 2026 Inovoice |
© 2026 Inovoice |
| 6. Tüm Türkçe Harfleri Entity Yapmak | Sayfadaki her Türkçe harfi ç yapmak HTML dosya boyutunu %30 şişirir ve SEO taramasını yavaşlatır. |
İstanbul çözüm |
Doğrudan UTF-8 düz metin kullanın: İstanbul çözüm (Entity yalnızca < > & " ' için zorunludur). |
Inovoice olarak kurumsal web projelerinde XSS, SQLi ve CSRF güvenlik açıklarına karşı uçtan uca kaynak kod denetimi, penetrasyon testi danışmanlığı ve yüksek güvenlikli özel yazılım mimarileri inşa ediyoruz.