HG PHP GüvenliğiEl Kitabı
Bölümler 09 / 38

İçindekiler/Enjeksiyon Sınıfı Açıklar

Bölüm 09

Server-Side Template Injection (SSTI)

13 dk okuma2.529 kelimePHP 8.1+
Ön koşul

Bölüm 5 (şablon motorları, auto-escaping), Bölüm 8 (RCE'nin ne demek olduğu).

Bu bölümün kazanımı

SSTI'yi, "kullanıcı verisini şablona veri olarak vermek" ile "kullanıcı verisini şablonun kendisi (kod) yapmak" arasındaki hayati farkın ihlali olarak kavrayacak; sunucu tarafı şablon motorlarının neden doğrudan RCE'ye açıldığını ve sandbox'ların neden yeterli bir savunma olmadığını göreceksiniz.

1. Giriş

Bölüm 5 ve 7'de şablon motorlarını (Twig, Blade, Smarty) XSS'e karşı bir savunma olarak tanıttık: auto-escaping, çıktı kodlamasını otomatikleştirir. Bu bölüm, aynı motorların yanlış kullanıldığında nasıl bir açık kaynağına dönüştüğünü inceler. İki yüz aynı madalyondadır.

Server-Side Template Injection, kullanıcı girdisinin bir şablona veri olarak değil, şablon kodunun kendisi olarak girmesiyle oluşur. Fark hayatidir. Bir şablon motoru, kendisine verilen şablon metnini çalıştırılabilir bir dil olarak yorumlar; içindeki ifadeleri değerlendirir, döngüleri işler, fonksiyonları çağırır. Kullanıcı bu metni kontrol edebiliyorsa, motorun tüm ifade değerlendirme gücünü de kontrol eder. Sunucu tarafı motorlarda bu güç, çoğu zaman doğrudan PHP kodu çalıştırmaya (RCE) kadar uzanır.

SSTI, 2015'te James Kettle'ın (PortSwigger) sistematik araştırmasıyla ayrı bir açık sınıfı olarak tanındı. O günden beri, kullanıcı girdisini şablonlara "esneklik olsun" diye gömen sayısız uygulamada — özellikle e-posta şablonu, tema, "özelleştirilebilir bildirim" gibi özelliklerde — ortaya çıktı. Etkisi ciddidir: XSS'in aksine SSTI, çoğunlukla istemcide değil sunucuda kod çalıştırır.


2. Temel Teori

SSTI'nin kök nedeni tanıdık kalıbın bir başka yüzüdür: güvenilmeyen veri, bir şablon motorunun onu kod olarak yorumlayacağı bir bağlama girer ve motor onu çalıştırır.

Kritik ayrımı netleştirelim. Bir şablon motorunun iki farklı kullanım biçimi vardır:

Doğru (veri olarak): Şablon sabittir (geliştirici yazar), kullanıcı verisi ona değişken olarak geçilir.

// Şablon sabit; $name bir DEĞİŞKEN olarak geçiyor — güvenli
$twig->render('hello.twig', ['name' => $userInput]);
// hello.twig içeriği: Merhaba {{ name }}

Yanlış (kod olarak): Şablonun kendisi kullanıcı girdisinden kuruluyor.

// ⚠️ Şablon METNİ kullanıcıdan geliyor — SSTI
$twig->createTemplate('Merhaba ' . $userInput)->render();

İkinci durumda $userInput, artık {{ }} içindeki ifadeler dahil, şablon dilinin tamamına erişebilir. Bu, SQL'de sorguyu, komut enjeksiyonunda kabuk komutunu kullanıcıya yazdırmak kadar tehlikelidir.

Neden RCE'ye varır? Sunucu tarafı şablon motorları, sunum kolaylığı için nesnelere, metotlara ve bazen doğrudan dil özelliklerine erişim sunar. Bir saldırgan, şablon ifadeleri aracılığıyla motorun eriştiği nesne grafiğinde gezinip (PHP'de sınıflar, statik metotlar, Reflection benzeri yollar) sonunda kod çalıştıran bir fonksiyona ulaşır. Motor "sadece bir şablon dili" gibi görünse de, altında PHP çalışmaktadır ve yeterince zengin bir motor, o PHP'ye köprü sunar.

Motor farkları. Motorlar tehlike düzeyine göre ayrışır. Mantıksız (logic-less) motorlar (ör. Mustache) sınırlı ifade gücü sunar; zengin motorlar (Twig, Smarty) çok daha fazlasını. Smarty gibi bazıları, PHP'yi şablona karıştırmaya tarihsel olarak izin verdiği için doğası gereği risklidir (Bölüm 11).


3. Mimarisel Bakış

 DOĞRU (veri olarak):
   Sabit şablon  +  $_POST['name'] (değişken)
        ↓
   Motor: "Merhaba {{ name }}"  →  name = kullanıcı verisi (SAF)
        ↓
   {{ }} yalnızca geliştiricinin yazdığı yerde → kullanıcı ifade YAZAMAZ

 YANLIŞ (kod olarak) — SSTI:
   "Merhaba " . $_POST['name']   →  ŞABLON METNİ kullanıcıdan
        ↓
   Motor, kullanıcı girdisini şablon DİLİ olarak ayrıştırır
        ↓  {{ 7*7 }} → 49 ... {{ tehlikeli_ifade }} → PHP nesne grafiği
        ↓
   RCE (sunucuda kod çalışır)

Güven sınırı burada şablon derleyicisinin girişindedir. Kullanıcı verisi bu sınırı "kod" olarak geçerse felaket; "değişken" olarak geçerse güvenli.


4. Güvensiz Kod

Gerçekçi bir "özelleştirilebilir e-posta/bildirim şablonu" özelliği — SSTI'nin en sık göründüğü yer:

<?php
// ⚠️ GÜVENSİZ — kullanıcı şablon METNİNİ kontrol ediyor (SSTI)
declare(strict_types=1);

// Kullanıcı, "hoş geldin e-postası" şablonunu panelden düzenleyebiliyor
$userTemplate = $_POST['email_template'];   // örn: "Merhaba {{ user.name }}, ..."

// Şablon, kullanıcı metninden RUNTIME'da oluşturuluyor
$template = $twig->createTemplate($userTemplate);
$body = $template->render(['user' => $currentUser]);

sendEmail($currentUser->email, $body);

// --- Başka bir yaygın kalıp: str_replace ile "kendi şablon dilini" uydurmak ---
$greeting = $_GET['greeting'];   // "Selam {name}"
$output = str_replace('{name}', $currentUser->name, $greeting);  // görece güvenli...
// ...ama bunu bir motora beslerlerse:
echo $smarty->fetch('string:' . $greeting);   // ⚠️ Smarty'ye string template → SSTI

5. Açığın Analizi

$twig->createTemplate($userTemplate) — Klasik SSTI. createTemplate, kendisine verilen dizeyi bir Twig şablonu olarak derler. Kullanıcı bu dizeyi kontrol ettiğinden, {{ }} ifadeleri dahil Twig'in tüm ifade gücüne erişir. {{ 7*7 }} yazıp yanıtta 49 görmek, motorun girdiyi değerlendirdiğinin kanıtıdır — ve buradan nesne grafiğinde gezinerek koda ulaşmak an meselesidir.

$smarty->fetch('string:' . $greeting) — Smarty'nin string: kaynağı, verilen dizeyi bir şablon olarak derler. Smarty tarihsel olarak PHP'yi şablona karıştırmaya yakın olduğundan (Bölüm 11), bu doğrudan PHP kod enjeksiyonuna varır.

str_replace('{name}', ...) — İlginç bir karşıt örnek: bu, bir şablon motoru olmadığı için (yalnızca dize değişimi) SSTI değildir; kullanıcı {name} dışında bir ifade yazsa da değerlendirilmez. Bunu örnek koyma nedenim: SSTI'nin tehlikesi motorun ifade değerlendirmesinden gelir, dize birleştirmeden değil. Ancak aynı $greeting bir motora beslenirse hemen SSTI'ye döner — yani "önemsiz görünen" bir alan, akış değiştiğinde patlayabilir.

Kök sorun: kullanıcı girdisi, bir ifade değerlendirici motorun program metni olarak kullanılıyor.


6. Hacker Bakış Açısı

Saldırgan SSTI'yi nasıl keşfeder? Bu, en "imzalı" keşif süreçlerinden biridir.

Değerlendirme (evaluation) sondası atar. Girdiye basit bir matematik ifadesi koyar (motorun sözdizimine göre {{7*7}}, ${7*7}, #{7*7}, {7*7} gibi) ve yanıtta ham metin yerine 49 görürse, girdinin bir ifade değerlendiricisine ulaştığını kesinleştirir. Bu, SSTI'nin en tanınmış parmak izidir; XSS'teki < sondasının SSTI karşılığıdır.

Motoru parmak izler. Farklı motorların sözdizimi farklıdır; hangi sondanın çalıştığına bakarak (Twig mi, Smarty mi, Blade mi, Jinja mi) motoru belirler. Motor bilinince, o motora özgü nesne-grafiği yolları devreye girer.

Nesne grafiğinde gezinir. Motor bilindiğinde, saldırgan şablon ifadeleri aracılığıyla erişilebilen nesnelerden, sınıf yükleyicilerden veya global fonksiyonlardan kod çalıştıran bir yola ulaşmaya çalışır. Sandbox varsa, onu aşan (escape) bilinen teknikleri dener.

SSTI'yi XSS'ten ayırır. {{7*7}} 49 döndürüyorsa SSTI (sunucuda değerlendirme); <script> yansıyorsa XSS (istemcide). Deneyimli saldırgan ikisini karıştırmaz çünkü etkileri ve savunmaları farklıdır.

Savunmacı dersi: {{7*7}}=49 sinyali, saldırgan için bir "kazandım" işaretidir. Bu sinyalin hiç oluşmaması için kullanıcı girdisi asla şablon metni olmamalıdır.


7. Exploit Mantığı

Çalıştırılabilir zincirler verilmez. SSTI'nin gücü kavramsaldır: saldırgan, şablon motorunun ifade değerlendiricisini ele geçirdiğinde, o motorun eriştiği her şeye erişir.

  • Doğrudan RCE: Sunucu tarafı motorlar, sunum için nesne/metot erişimi sunar. Yeterince zengin bir motorda saldırgan, bu erişimi bir kod-çalıştırma fonksiyonuna köprülemenin bir yolunu bulur. Sonuç, komut enjeksiyonuyla (Bölüm 8) aynı: sunucuda kod.
  • Bilgi ifşası: Kod çalıştırılamasa bile, saldırgan uygulama nesnelerine, yapılandırmaya, ortam değişkenlerine (gizli anahtarlar!) erişip veri sızdırabilir.
  • Sandbox aşımı: Bazı motorlar bir "sandbox" modu sunar (yalnızca izinli fonksiyonlar). Ancak sandbox'lar tarihsel olarak aşılmıştır (Smarty örneği, Bölüm 11): motorun iç nesnelerine erişimin tek bir yolu bile, sandbox'ı etkisiz kılar. Bu yüzden sandbox, "kullanıcıya şablon yazdırmak güvenli" demenin gerekçesi olamaz.

Araştırmacının çerçevesi: (a) hangi motor ve sandbox var mı, (b) ifade değerlendirici hangi nesnelere erişiyor, (c) o nesnelerden koda/veriye giden yol var mı. Savunma tarafı ise bu zincirin başlangıcını keser: kullanıcı hiç şablon yazmasın.


8. Güvenli Kod

Temel ilke: kullanıcı girdisi asla şablon metni olmaz; daima değişken olarak geçer.

<?php
// ✅ GÜVENLİ — sabit şablon + kullanıcı verisi DEĞİŞKEN olarak
declare(strict_types=1);

// Şablon geliştirici tarafından yazılır ve dosyadan yüklenir (sabit)
$body = $twig->render('emails/welcome.twig', [
    'user'    => $currentUser,     // kullanıcı verisi: değişken (güvenli)
    'company' => $company,
]);
sendEmail($currentUser->email, $body);
{# emails/welcome.twig — SABİT şablon; kullanıcı bunu düzenleyemez #}
Merhaba {{ user.name }},
{{ company.name }} ailesine hoş geldiniz.

Peki kullanıcının gerçekten şablonu özelleştirmesi gerekiyorsa (e-posta düzenleyici gibi)? Şablon dili vermek yerine, kısıtlı ve motorsuz bir yer-tutucu (placeholder) sistemi kurun:

<?php
// ✅ GÜVENLİ — motor değil, beyaz-listeli yer tutucu değişimi
declare(strict_types=1);

$userTemplate = $_POST['email_template'];   // "Merhaba {{name}}, kodun: {{code}}"

// Yalnızca izinli yer tutucular; ifade değerlendirme YOK
$allowed = [
    '{{name}}'  => $currentUser->name,
    '{{email}}' => $currentUser->email,
    '{{code}}'  => $verificationCode,
];

// strtr ifade DEĞERLENDİRMEZ; yalnızca birebir metin değişimi yapar
$body = strtr($userTemplate, array_map(
    fn($v) => htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'),
    $allowed
));
// Not: {{name}} dışında ne yazarlarsa yazsınlar, hiçbiri "kod" olarak çalışmaz.

Zorunlu olarak gerçek bir motor kullanılacaksa (nadir, gelişmiş senaryolar), şu katmanlar birlikte gerekir: mantıksız/kısıtlı bir motor, sandbox modu (tek savunma olarak değil), izole ve en az yetkili bir süreç (Bölüm 28–29). Ancak varsayılan tavsiye nettir: kullanıcıya Turing-tam bir şablon dili vermeyin.

Öne çıkan kalıplar: - Sabit şablon + değişken veri: SSTI'yi kökten önleyen mimari. - strtr/beyaz-listeli placeholder: Özelleştirme gerektiğinde motorsuz, değerlendirmesiz çözüm. - Güncel motor sürümü: Kullanmak zorundaysanız, sandbox-aşım yamaları uygulanmış son sürüm (Bölüm 30).


9. Patch Analizi

Neden işe yarar? Kullanıcı girdisi bir değerlendiriciye hiç ulaşmaz. strtr/str_replace yalnızca birebir metin değişimi yapar; {{7*7}} yazılsa bile bu bir ifade değil, eşleşmeyen bir dizedir ve olduğu gibi kalır. SSTI'nin başlangıç koşulu (kullanıcı girdisi = şablon metni) ortadan kalkar.

Alternatif karşılaştırması:

Yaklaşım SSTI riski Not
Kullanıcı girdisi = şablon metni Yüksek (RCE) Asla yapılmaz
Sandbox'lı motor + kullanıcı şablonu Orta Sandbox aşılabilir; tek savunma olamaz
Sabit şablon + değişken veri Yok Önerilen mimari
strtr beyaz-listeli placeholder Yok Özelleştirme gerektiğinde
Mantıksız motor (Mustache) Düşük İfade gücü sınırlı; yine de girdi=veri olmalı

Performans: strtr/sabit şablon, kullanıcı şablonunu runtime'da derlemekten genellikle daha hızlıdır (derleme maliyeti yok). Güvenlik ve performans burada aynı yöne işaret eder.


10. Gerçek Hayat Senaryosu

Kurgu — bir pazarlama otomasyonu (e-mail marketing) SaaS'ı. Ürünün öne çıkan özelliği, müşterilerin e-posta şablonlarını "değişkenlerle" zenginleştirebilmesi. Geliştiriciler, esneklik için müşteri şablonunu doğrudan Twig'e createTemplate ile besliyor. Bir müşteri (hatta ücretsiz deneme hesabı), şablon alanına bir değerlendirme sondası koyup SSTI'yi keşfediyor ve sunucuda kod çalıştırıyor. Bu, çok kiracılı bir SaaS olduğu için, tek bir düşük yetkili müşteri hesabı üzerinden tüm platformun ve diğer müşterilerin verisinin ele geçirilmesine kadar tırmanıyor. Dersler: (1) "esneklik" için kullanıcıya şablon dili vermek, ona sunucuda kod çalıştırma yeteneği vermektir; (2) placeholder tabanlı özelleştirme aynı ürün değerini SSTI riski olmadan sağlardı; (3) izolasyon (Bölüm 29) hasarı sınırlardı.


11. Gerçek CVE Analizi — Smarty Sandbox Escape (CVE-2021-26120 / CVE-2021-26119)

MITRE/NVD kayıtları, GitHub Advisory, satıcı sürüm notları ve kaşif (Steven Seeley / Source Incite) yayınıyla doğrulanmıştır. Silahlaştırılmış zincir verilmez; mekanizma ve dersler incelenir.

Özet. 2021'in başında, yaygın PHP şablon motoru Smarty'de iki ilişkili açık açıklandı. CVE-2021-26120, 3.1.39 öncesi sürümlerde, bir {function name= alt dizesinden sonra gelen beklenmeyen bir fonksiyon adı aracılığıyla kod enjeksiyonuna izin veriyordu. CVE-2021-26119, sandbox modundayken $smarty.template_object özelliğine erişilebilmesi nedeniyle bir sandbox aşımına (escape) yol açıyordu. Her ikisi de 3.1.39 ile düzeltildi.

Teknik neden. CVE-2021-26120'nin kökü, Smarty şablon derleyicisindeki yetersiz girdi doğrulamasıydı: {function} etiketini işleyen mantık, üretilen PHP koduna dahil etmeden önce fonksiyon adını yeterince doğrulamıyordu. Böylece özel biçimlendirilmiş bir fonksiyon adı, tasarlanan bağlamdan "kaçıp" derlenmiş şablona keyfi PHP ifadeleri enjekte edebiliyordu. Kritik olan şudur: bu açık, sandbox sertleştirmesiyle bile azaltılamıyordu (3.1.38 ve altında), çünkü sorun çalışma zamanı kısıtlamasında değil, derleme aşamasının kendisindeydi.

CVE-2021-26119 ise sandbox'ın bir mantık açığıydı: sandbox, tehlikeli erişimleri kısıtlamaya çalışırken $smarty.template_object'e erişimi kapatmayı atlamıştı; bu tek açık kapı, sandbox'tan çıkıp motorun iç nesnelerine ulaşmaya ve RCE'ye yetiyordu. Bu, Bölüm 7'deki "tek bir açık, tüm savunmayı etkisiz kılar" ilkesinin sandbox'lardaki karşılığıdır.

Etki. Smarty'yi kullanan popüler CMS'ler (CMS Made Simple, Tiki Wiki) etkilendi; araştırmacı, bu açıkları başka açıklarla (kimlik doğrulama atlatma, SQLi) zincirleyerek kimlik doğrulaması gerektirmeyen uzaktan kod çalıştırmayı gösterdi. Ayrıca araştırmacının önemli bir gözlemi vardı: üçüncü parti uygulamalar Smarty'yi sıklıkla güvensiz yapılandırıyor ve çoğu zaman sandbox'ı hiç kullanmıyordu — bu da RCE'yi daha da kolaylaştırıyordu.

Satıcı düzeltmesi. Smarty 3.1.39, hem fonksiyon-adı doğrulamasını hem de sandbox'taki template_object sızıntısını kapattı.

Çıkarılacak dersler: 1. Sandbox, kullanıcıya şablon yazdırmayı güvenli kılmaz. Sandbox'lar aşılabilir (26119) ve bazı açıklar sandbox'ın hiç dokunamadığı derleme aşamasındadır (26120). Sandbox bir savunma katmanıdır, bir garanti değil. 2. Şablon motorları da güvensiz yapılandırılır. Bir motoru kullanmak, onu güvenli kullanmakla aynı şey değildir; varsayılanlar ve dokümantasyon dikkatle okunmalıdır (Bölüm 3). 3. Bağımlılık güncelliği kritiktir. 3.1.39'a yükselmeyen her uygulama, kamuya açık bir RCE zincirine maruz kaldı (Bölüm 30).


12. Detection

Kod incelemede: Kullanıcı girdisinin bir şablon derleyicisine/render'ına metin olarak ulaştığı yerleri arayın:

grep -rnE 'createTemplate|->render\(\s*\$|fetch\(.*string:|display\(.*\$' src/
grep -rn  'twig->createTemplate|Environment.*createTemplate'            src/
grep -rn  "'string:'\|eval resource"                                     src/   # Smarty string/eval

Soru: render/display'in ilk argümanı (şablon) sabit mi, yoksa kullanıcıdan mı geliyor? İkinci argüman (veri) kullanıcıdan gelebilir; birincisi asla.

SAST: Kaynaktan ($_POST) şablon-derleme sink'ine (createTemplate, fetch('string:...')) taint izini yakalar. SSTI kuralları, motor-farkında araçlarda mevcuttur.

DAST: Değerlendirme sondalarıyla ({{7*7}}, ${7*7}, #{7*7} vb.) yanıtta 49 arayarak SSTI'yi otomatik tespit eder — en güvenilir dinamik sinyallerden biri.

Loglar/SIEM: Girişte şablon-sözdizimi kalıpları ({{, ${, {php}, {function) ve — Smarty gibi motorlarda — beklenmeyen derleme/önbellek dosyalarının oluşması. Web sürecinden beklenmeyen alt süreçler (Bölüm 8) yine RCE'nin işaretidir.


13. Prevention

  • Kullanıcı girdisini asla şablon metni yapmayın. Sabit şablon + değişken veri mimarisi birincil savunmadır.
  • Özelleştirme için motorsuz placeholder (strtr/beyaz liste) kullanın; ifade değerlendirmesi gerektirmez.
  • Zorunlu motorda: mantıksız/kısıtlı motor + güncel sürüm + sandbox (tek başına değil) + izolasyon.
  • Threat modeling: "Kullanıcı şablon/tema/bildirim düzenleyebiliyor mu?" sorusunu her özellikte sorun (Bölüm 2).
  • Bağımlılık güncelliği: Şablon motorlarını (özellikle Smarty/Twig) yamalı tutun (Bölüm 30).

14. Mitigation

  • Acil: Kullanıcı-şablonu özelliğini devre dışı bırakın veya placeholder tabanlı sürüme geçirin; şablon motorunu son sürüme yükseltin.
  • Geçici: Derleme/önbellek dizinlerini ve süreç loglarını inceleyerek istismar kapsamını belirleyin; web shell/backdoor tarayın (Bölüm 34); sızmış olabilecek gizli anahtarları döndürün (SSTI ortam değişkenlerini ifşa edebilir).
  • Kalıcı: Sabit şablon + değişken veri mimarisine geçin; izolasyon ve SCA taraması ekleyin.

15. Checklist

  • [ ] render/display/createTemplate'in şablon argümanı daima sabit mi (kullanıcıdan gelmiyor)?
  • [ ] Kullanıcı verisi yalnızca değişken olarak mı geçiyor?
  • [ ] Kullanıcı özelleştirmesi gerekiyorsa motorsuz placeholder (strtr) mı kullanılıyor?
  • [ ] Sandbox, "kullanıcı şablonu güvenli" gerekçesi olarak tek başına kullanılmıyor mu?
  • [ ] Şablon motoru (Smarty/Twig) güncel ve yamalı mı?
  • [ ] Motoru çalıştıran süreç izole ve en az yetkili mi?
  • [ ] Değerlendirme sondası ({{7*7}}) yanıtta değerlendirilmediği test edildi mi?

16. Laboratuvar

Lab 9.1 — Değerlendirme sondası. İzole ortamda createTemplate($_GET['x'])->render() kurup {{7*7}} girdisinin 49 döndürdüğünü gözlemle (SSTI kanıtı). Sonra sabit şablon + değişken veriye geçip aynı girdinin ham metin kaldığını doğrula.

Lab 9.2 — Placeholder çözümü. Kullanıcı e-posta şablonu özelliğini strtr + beyaz liste ile kur. {{7*7}} ve motor sözdizimi içeren girdilerin neden hiç değerlendirilmediğini açıkla.

Lab 9.3 — Sandbox sınırı. (Kavramsal) Bir motorun sandbox belgelerini okuyup "sandbox neyi garanti eder, neyi etmez?" sorusuna yanıt yaz; CVE-2021-26119'un sandbox'ı nasıl aştığını kendi cümlelerinle özetle.


17. Quiz

  1. SSTI'nin kök nedeni nedir? "Veri olarak" ile "kod olarak" şablon kullanımı arasındaki fark nedir?
  2. Neden sunucu tarafı SSTI çoğunlukla RCE'ye varır, oysa istemci-tarafı XSS sunucuda kod çalıştırmaz?
  3. {{7*7}}=49 sinyali neden SSTI'nin parmak izidir? Bunu XSS'ten nasıl ayırırsınız?
  4. $twig->render('file.twig', ['name' => $x]) ile $twig->createTemplate($x)->render() arasındaki güvenlik farkı nedir?
  5. strtr/str_replace neden SSTI değildir? Bu neden özelleştirme için güvenli bir çözümdür?
  6. Sandbox nedir ve neden "kullanıcıya şablon yazdırmak güvenli" demenin gerekçesi olamaz?
  7. CVE-2021-26120, sandbox sertleştirmesiyle bile neden azaltılamıyordu?
  8. CVE-2021-26119 sandbox'ı nasıl aştı? Bu, XSS/CSP'deki hangi ilkeye benzer?
  9. Kullanıcının gerçekten şablon özelleştirmesi gereken bir üründe SSTI riski olmadan aynı değeri nasıl sağlarsınız?
  10. Kod incelemede SSTI ararken render/display'in hangi argümanına bakarsınız ve neden?

18. Kaynakça

  • OWASP, Server-Side Template Injection (WSTG) ve ilgili test rehberi.
  • James Kettle (PortSwigger), Server-Side Template Injection araştırması (2015).
  • MITRE, CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine; CWE-94: Code Injection.
  • MITRE / NVD, CVE-2021-26120 ve CVE-2021-26119 kayıtları; GitHub Advisory (GHSA).
  • Steven Seeley / Source Incite, Smarty Template Engine Multiple Sandbox Escape danışma yazısı.
  • Smarty CHANGELOG ve 3.1.39 sürüm notları; Twig Security dokümantasyonu (sandbox).