LLM05 Hatalı Çıktı İşleme Nedir?
LLM çıktısından XSS ve SQL injection'a giden yol
Bir dil modelinin ürettiği metni "temiz veri" sanıp doğrudan tarayıcıya, veritabanına veya kabuğa iletmek, prompt injection'ı klasik bir web zafiyetine dönüştürür. OWASP'ın LLM05 maddesi tam da bu köprüyü, yani modelin çıktısını güvenilmez girdi gibi ele almamayı anlatır.
LLM05 Hatalı Çıktı İşleme nedir?
LLM05 Hatalı Çıktı İşleme (Improper Output Handling), OWASP'ın 2025 tarihli LLM Uygulamaları için En Kritik 10 Risk listesinde beşinci sırada yer alan zafiyet sınıfıdır. Tek cümleyle: bir dil modelinin ürettiği çıktının, güvenilmez bir girdi gibi doğrulanıp temizlenmeden alt bileşenlere (web tarayıcısı, veritabanı, işletim sistemi kabuğu, dosya sistemi, e-posta istemcisi) aktarılmasıdır. Model çıktısı zararsız düz metin sanıldığında ve doğrudan bir HTML sayfasına, SQL sorgusuna veya kabuk komutuna gömüldüğünde, saldırganın prompt'a yerleştirdiği yük artık modelin "cevabı" gibi görünerek klasik enjeksiyon zafiyetlerini tetikler.
Önemli ayrım şudur: LLM05 modelin ne düşündüğüyle değil, uygulamanın modelin ürettiğini nasıl kullandığıyla ilgilenir. Prompt injection (LLM01) saldırının giriş kapısıysa, hatalı çıktı işleme çıkış kapısıdır. İkisi çoğu zaman bir zincirin iki ucudur: kötü niyetli girdi modele ulaşır, model bunu çıktısına taşır, uygulama da bu çıktıyı körlemesine icra eder.
Neden LLM çıktısı "güvenilmez girdi" sayılmalı?
Geleneksel güvenlik zihniyeti girdiyi (kullanıcı formu, API parametresi) güvensiz, sistemin kendi ürettiğini güvenli kabul eder. Dil modelleri bu ayrımı bozar. Model, çıktısını beslediği bağlamdan (sistem promptu, kullanıcı mesajı, RAG ile getirilen doküman, bir aracın döndürdüğü veri) üretir. Bu kaynakların herhangi biri saldırgan tarafından kontrol edilebiliyorsa, çıktı da fiilen saldırgan kontrolündedir.
Dolaylı prompt injection bunu görünmez kılar: bir web sayfasında, PDF'te veya e-postada gizlenmiş talimat modele ulaşır ve çıktıya sızar. Bu mekanizmayı ayrı olarak dolaylı enjeksiyon: HTML, PDF ve e-posta vektörleri yazımızda ele aldık. LLM05 açısından kritik nokta net: modelin ürettiği her karakter, en az kullanıcının doğrudan yazdığı kadar güvensizdir. Uygulama katmanı bu varsayımla tasarlanmadığında, model bir enjeksiyon taşıyıcısına dönüşür.
Riski büyüten üç yapısal etken vardır:
- Görünürdeki masumiyet: Model çıktısı akıcı, doğal ve "yardımcı" göründüğü için geliştiriciler onu sorgulamadan render eder.
- Zengin biçimlendirme: Markdown, HTML ve kod bloklarını üreten modeller, aktif içerik (script, iframe, img onerror) üretmeye de doğal olarak yatkındır.
- Ajan mimarileri: Model çıktısı bir aracı (araç çağrısı, SQL üretimi, kabuk komutu) tetiklediğinde, hatalı çıktı işleme doğrudan yürütmeye dönüşür.
Çıktıdan XSS ve SQL injection'a giden yol
LLM05'in en yaygın iki tezahürü, modern web güvenliğinin klasikleridir: siteler-arası betik çalıştırma (XSS) ve SQL injection. Zincir her ikisinde de aynıdır: saldırgan girdiyi zerk eder → model bunu çıktıya taşır → uygulama çıktıyı kodlamadan icra eder.
XSS: çıktının doğrudan render edilmesi
Bir sohbet arayüzü modelin yanıtını Markdown'dan HTML'e çevirip doğrudan DOM'a bastığında, model üretimi bir <img> etiketi tarayıcıda çalışır:
// ZAFİYETLİ: model çıktısı doğrudan innerHTML'e
const html = markdownToHtml(model.output);
chatWindow.innerHTML = html; // <img src=x onerror=fetch('/steal?c='+document.cookie)> çalışır
// GÜVENLİ: bağlama özel kodlama + izin listeli sanitizer
const clean = DOMPurify.sanitize(markdownToHtml(model.output), {
ALLOWED_TAGS: ['p','strong','em','ul','ol','li','code','pre'],
ALLOWED_ATTR: []
});
chatWindow.innerHTML = clean;SQL injection: çıktının sorguya birleştirilmesi
Doğal dilden SQL üreten (text-to-SQL) veya model yanıtını sorguya gömen uygulamalar aynı hatayı yapar:
| Yaklaşım | Davranış | Sonuç |
|---|---|---|
String birleştirme (f"...{model_out}...") | Çıktı sorgunun sözdizimine karışır | SQL injection, veri sızıntısı/silme |
| Parametreli sorgu (prepared statement) | Çıktı yalnızca veri olarak bağlanır | Enjeksiyon yüzeyi kapanır |
| İzin listeli şema doğrulaması | Yalnızca beklenen tablo/kolon kabul edilir | text-to-SQL için ek katman |
Aynı prensip komut enjeksiyonu, sunucu taraflı şablon enjeksiyonu (SSTI), yol atlama (path traversal) ve LDAP enjeksiyonu için de geçerlidir. Değişen tek şey hedef yorumlayıcıdır; kök neden hep aynıdır: çıktının hedefe göre kodlanmaması.
"When prompts become shells": prompt→çıktı→RCE zinciri
2026'da güvenlik topluluğunda "When prompts become shells" (promptlar kabuğa dönüşünce) başlığıyla anılan bir bulgu dalgası, LLM çerçevelerinde prompt injection'ın uzaktan kod yürütmeye (RCE) uzanabildiğini gösterdi. Bu dalganın öne çıkan gerçek örnekleri şunlardır:
- CrewAI RCE zinciri: Çoklu ajan çerçevesinde prompt injection ile başlayan bir zincir uzaktan kod yürütmeye ulaşabiliyordu. CERT/CC bu sorunları VU#221883 altında (CVE-2026-2275, -2285, -2286, -2287) belgeledi.
- Semantic Kernel CVE-2026-25592: Aynı dalgada, Microsoft'un Semantic Kernel çerçevesinde prompt injection'dan RCE'ye giden ayrı bir zafiyet raporlandı.
- Semantic Kernel CVE-2026-26030: InMemoryVectorStore filtresindeki bir kod-enjeksiyonu, CVSS 9.8 ile uzaktan kod yürütmeye yol açıyordu; sorun Python paketinin 1.39.4 sürümünde giderildi (GHSA-xjw9-4gw8-4rqx).
Doğru bağlam önemli: CVE-2026-26030 teknik olarak bir filtre ifadesinin sunucuda değerlendirilmesinden (eval enjeksiyonu) kaynaklanır; klasik "LLM çıktısını sanitize etmeme" tanımıyla birebir aynı kutucuk değildir. Ancak bu CVE'ler birlikte, LLM05'in neden bu kadar kritik olduğunu anlatan aynı büyük resmi çizer: bir dil modeli boru hattında güvenilmez metin, uygun sınır kontrolü olmadan icra edilen bir arayüze ulaştığında, sonuç metinden koda geçer. Hatalı çıktı işleme bu zincirin "çıktı→icra" halkasıdır; güvensiz değerlendirme (eval) ise onu RCE'ye tamamlar. OWASP LLM Top 10'un Türkçe genel bakışını OWASP LLM Top 10 Türkçe rehberinde bulabilirsiniz.
Türkçe çıktı-istismarı örüntüleri
AltaySec Scanner'ın kendi payload kütüphanesinde tuttuğumuz test örüntülerinden bazıları, çıktı-istismarını Türkçe bağlamda değerlendirmek için tasarlanmıştır. Aşağıdaki örnekler AltaySec'in kendi iç test varlığıdır; gerçek bir CVE kanıt kodu (PoC) değildir ve yalnızca savunma testleri için kullanılır. Amaç, bir modelin ürettiği yanıtın alt sistemlerde nasıl aktif içeriğe dönüşebileceğini ölçmektir.
- Biçimlendirme kaçışı: Modelden Türkçe bir tabloyu "HTML olarak" biçimlendirmesi istendiğinde, çıktıya
onerrorgibi olay işleyicilerin sızıp sızmadığını sınayan girdiler. - Markdown-link zerki: Türkçe talimatların içine gömülü, model tarafından yeniden üretildiğinde
javascript:şemasına dönüşen bağlantı örüntüleri. - Text-to-SQL sınırı: Türkçe doğal dil sorgularının, izin listesi dışı tablo/kolon adlarını çıktıya taşımaya çalışması.
Türkçe'nin morfolojik zenginliği ve İngilizce-Türkçe kod karışımı, çıktı filtrelerini atlatmak için ek yüzey açar; bu bypass örüntülerini Türkçe morfolojik LLM bypass yazımızda ayrıca inceledik. Çıktı güvenliği testinin Türkçe'ye özgü bu katmanı, İngilizce merkezli filtrelerin çoğu zaman ıskaladığı bir noktadır.
Kod seviyesinde sanitizasyon checklist'i
LLM05 savunmasının özü tek bir ilkeye dayanır: model çıktısını, hedeflediği yorumlayıcıya göre kodla ve doğrula. Aşağıdaki kontrol listesi, çıktı boru hattını sertleştirmek için pratik bir çerçeve sunar:
- Sıfır güven varsayımı: Model çıktısını her zaman kullanıcı girdisiyle aynı güvensizlik seviyesinde ele al. "Kendi modelimiz üretti" güvence değildir.
- Bağlama özel kodlama (output encoding): HTML gövdesi, HTML özniteliği, JavaScript, URL ve CSS bağlamlarının her biri için ayrı kodlama uygula; tek bir genel kaçış yeterli değildir.
- İzin listeli sanitizasyon: HTML render'da izin verilen etiket/öznitelik listesiyle çalışan bir sanitizer (ör. DOMPurify) kullan; kara liste yaklaşımından kaçın.
- Parametreli sorgu: Model çıktısı hiçbir zaman SQL/NoSQL/LDAP sorgusuna string olarak birleştirilmesin; yalnızca bağlı parametre olarak geçsin.
- Komut yürütmeyi izole et: Ajan araç çağrılarında kabuğu doğrudan çağırma; argümanları dizilim (array) olarak geçir, güvenli değerlendirme (eval) API'lerinden kaçın, sandbox uygula.
- Markdown/link denetimi:
javascript:,data:ve dosya şemalı bağlantıları reddet; otomatik bağlantı üretimini sınırla. - Şema doğrulaması: Yapılandırılmış çıktı bekleniyorsa (JSON), katı bir şemayla doğrula; beklenmeyen alanları düşür.
- Çıkış katmanı guardrail'i: Çıktıyı alt sisteme iletmeden önce bir güvenlik duvarından geçir.
Bu son madde için çalışma zamanı LLM guardrail'leri yazımızdaki çıkış filtresi desenleri doğrudan uygulanabilir. AltaySec Guardian gibi bir LLM güvenlik duvarı, model ile alt sistem arasına konumlanarak çıktı-istismarı örüntülerini icra edilmeden yakalamak için ek bir savunma hattı sağlar. Yine de mimari ilke değişmez: guardrail, hedefe özel kodlama ve parametreli sorgunun yerine değil, üzerine gelir.
Özet: çıktı da bir saldırı yüzeyidir
LLM05 Hatalı Çıktı İşleme, dil modeli uygulamalarında en sık gözden kaçan sınır ihlallerinden biridir çünkü modelin "cevabı" içgüdüsel olarak güvenilir görünür. Oysa bu cevap, saldırgan tarafından kontrol edilebilen bir bağlamın ürünüdür ve doğrulanmadan icra edildiğinde XSS, SQL injection ve — 2026'nın "promptlar kabuğa dönüşünce" dalgasında görüldüğü üzere — uzaktan kod yürütmeye kadar uzanır.
Doğru zihniyet basittir: modelin ürettiği her şeyi güvensiz girdi say, hedefe göre kodla, parametrele ve izin listesiyle doğrula. Prompt injection'ı bir web zafiyetine çeviren köprü, ancak çıktı katmanı ciddiye alındığında kapanır. Kurumsal LLM boru hattınızda çıktı güvenliği denetimi için bizimle iletişime geçebilirsiniz.
