14 Kasım 2026 CumartesiRSS

AI Güvenliği

Prompt Injection'dan RCE'ye: Semantic Kernel ve AI Ajan Güvenliği

Aziz Özdemiroğlu

Bir yapay zekâ ajanına "şu web sayfasını özetle" dediğinizde, o sayfadaki gizli bir metin ajanınızın sunucunuzda komut çalıştırmasına yol açabilir mi? Microsoft'un 2026'da Semantic Kernel'de bulduğu iki açık, cevabın "evet" olabileceğini gösterdi. Bu yazıda istem enjeksiyonunun (prompt injection) nasıl uzaktan kod çalıştırmaya (RCE) dönüştüğünü, etkilenen sürümleri ve ajan geliştirirken uygulamanız gereken tasarım ilkelerini kod örnekleriyle anlatıyoruz.

Kısaca

  • CVE-2026-26030: Semantic Kernel Python paketinin 1.39.4 öncesi sürümlerinde, In-Memory Vector Store'un varsayılan filtresi model kontrolündeki argümanlarla bir Python lambda'sı üretip eval() ile çalıştırıyordu. Düzeltme: 1.39.4+.
  • CVE-2026-25592: Semantic Kernel .NET SDK'nın 1.71.0 öncesi sürümlerinde DownloadFileAsync yanlışlıkla modele araç (tool) olarak açılmıştı. Bu da hostta keyfi dosya yazmaya, örneğin Windows Başlangıç klasörüne yazmaya izin veriyordu. Düzeltme: 1.71.0+.
  • Microsoft'un temel mesajı: LLM bir güvenlik sınırı değildir. Modelin etkileyebildiği her araç parametresini saldırgan kontrolünde kabul edin.
  • Benzer bir sınıf, Cursor için bildirilen CVE-2026-22708 ile kodlama ajanlarında da görüldü: izin listesindeki (allowlist) komutlar zararlı yük taşıyacak şekilde ortam zehirlendi.

İstem enjeksiyonu neden "yeni SQL enjeksiyonu"?

Klasik SQL enjeksiyonunda kullanıcı verisi kodla karışır. İstem enjeksiyonunda ise güvenilmeyen içerik, yani web sayfaları, e-postalar, belgeler veya araç çıktıları, modelin talimatlarıyla aynı kanala girer. Model, "bu metin veri mi, talimat mı?" ayrımını güvenilir biçimde yapamaz.

Ajan mimarilerinde bu sorun büyür, çünkü model artık yalnızca metin üretmez, araç çağırır:

Güvenilmeyen içerik ──► LLM ──► araç çağrısı (parametreleri model üretir) ──► kod/dosya/ağ
        ▲                                                                     │
   saldırganın metni                                       gerçek dünyadaki etki ◄┘

Enjeksiyon giriş kapısıdır. Asıl hasarı ise araç katmanındaki güvensiz bir "sink" verir: eval, kabuk komutu, dosya yazma, SQL sorgusu gibi.

Vaka 1: CVE-2026-26030 — vektör aramasında eval()

Semantic Kernel'in Python paketinde, In-Memory Vector Store ile desteklenen bir arama eklentisi (Search Plugin) varsayılan yapılandırmada kullanıldığında, filtre ifadesi model tarafından üretilen argümanların metin birleştirmeyle bir Python lambda'sına yerleştirilmesiyle oluşturuluyor ve eval() ile çalıştırılıyordu. Bir engel listesi (AST kontrolleri) vardı ama atlatılabildi.

Ön koşullar: (1) bir istem enjeksiyonu vektörü, örneğin ajanın okuduğu bir belge, ve (2) varsayılan ayarlarla In-Memory Vector Store destekli arama eklentisi.

Düzeltme (1.39.4): AST düğüm türleri için izin listesi, fonksiyon çağrısı izin listesi, tehlikeli öznitelik engel listesi ve isim düğümü kısıtlaması.

Ders: engel listesi değil, izin listesi

# YANLIŞ: model çıktısını koda dönüştürmek
filter_fn = eval(f"lambda r: r['{field}'] == '{value}'")   # field/value modelden geliyor!

# DOĞRU: yapılandırılmış filtre + izin listesi
ALLOWED_FIELDS = {"category", "language", "year"}

def build_filter(field: str, value: str):
    if field not in ALLOWED_FIELDS:
        raise ValueError(f"İzin verilmeyen alan: {field}")
    return lambda r: r.get(field) == value   # değer veri olarak kalır, koda dönüşmez

Vaka 2: CVE-2026-25592 — yanlışlıkla açılan dosya yazma aracı

.NET SDK'da SessionsPythonPlugin içindeki DownloadFileAsync metodu yanlışlıkla [KernelFunction] özniteliğiyle işaretlenmişti. Bu, modelin hosttaki yerel dosya yolunu (localFilePath) serbestçe seçebildiği, yol doğrulaması olmayan bir araç demekti. Enjekte edilmiş bir istem, ajanı Windows Başlangıç (Startup) klasörüne dosya yazmaya yönlendirip kalıcı kod çalıştırma elde edebiliyordu. Microsoft, Python ve .NET SDK'larındaki upload_file fonksiyonunda da benzer bir keyfi dosya okuma sorunu olduğunu belirtiyor.

Düzeltme (1.71.0): [KernelFunction] özniteliği kaldırıldı. Yol kanonikleştirmesi ve izin listesi eşleştirmesi yapan ValidateLocalPathForDownload() eklendi.

Ders: araç yüzeyini bilinçli tasarlayın

from pathlib import Path

SANDBOX = Path("/srv/agent-workspace").resolve()

def safe_path(user_path: str) -> Path:
    """Model tarafından verilen yolu sandbox içine kilitler."""
    p = (SANDBOX / user_path).resolve()
    if not p.is_relative_to(SANDBOX):   # ../../ ve sembolik bağ kaçışlarını engeller
        raise PermissionError("Sandbox dışı yol reddedildi")
    return p

Etkilenen sürümler ve yapılacaklar

CVE Bileşen Etkilenen Düzeltilmiş Etki
CVE-2026-26030 semantic-kernel (PyPI) < 1.39.4 1.39.4 eval() ile RCE
CVE-2026-25592 Semantic Kernel .NET SDK < 1.71.0 1.71.0 Keyfi dosya yazma → kalıcılık
# Python
pip show semantic-kernel | grep -i version
pip install --upgrade "semantic-kernel>=1.39.4"

# .NET
dotnet list package | grep -i SemanticKernel
dotnet add package Microsoft.SemanticKernel --version 1.71.0   # veya daha yenisi

Microsoft'un önerdiği olay sonrası adımlar:

  1. Her dağıtım için savunmasız pencereyi belirleyin: savunmasız sürümün yayına alındığı tarihten yükseltmeye kadar geçen süre.
  2. Bu pencerede host seviyesinde istismar sonrası sinyalleri arayın. Örneğin ajan sürecinin cmd, powershell, certutil, curl gibi alt süreçler başlatması.
  3. Şüpheli durumda hostu ele geçirilmiş kabul edin. Ajanın erişebildiği tüm kimlik bilgilerini ve token'ları yenileyin.

Ajan geliştirme için 10 güvenlik ilkesi

  • LLM'i güvenlik sınırı saymayın. Model çıktısı kullanıcı girdisi kadar güvenilmezdir.
  • Araç parametrelerini doğrulayın. Tür, aralık, izin listesi ve yol kanonikleştirmesi kullanın.
  • eval/exec/kabuk birleştirme yasak. Komut çalıştırmanız gerekiyorsa argümanları liste olarak verin (subprocess.run([...], shell=False)).
  • En az ayrıcalık: Ajan süreci ayrı bir kullanıcıyla, container veya sandbox içinde, salt okunur dosya sistemiyle çalışsın.
  • Araç yüzeyini küçük tutun. Her [KernelFunction] veya @tool dekoratörü bir saldırı yüzeyidir. Kod incelemesinde özellikle bakın.
  • Yüksek etkili eylemlerde insan onayı: Dosya silme, para transferi, e-posta gönderme, üretime dağıtım.
  • Ağ çıkışını kısıtlayın. Ajan yalnızca gereken alan adlarına bağlanabilsin. Bu, veri sızdırmayı zorlaştırır.
  • İzin listesi tuzağına dikkat: Cursor vakasında (CVE-2026-22708) otomatik onaylanan git branch gibi "zararsız" komutlar, zehirlenmiş ortam üzerinden yük taşıdı. İzin listesi komut adına değil, tam komut ve ortama bakmalı.
  • Kimlik bilgilerini ajandan uzak tutun. Kısa ömürlü, kapsamı dar token'lar kullanın ve ortam değişkenlerine uzun ömürlü anahtar koymayın.
  • AI katmanı ile host katmanı sinyallerini birleştirin. İçerik güvenliği filtresi uyarısı ile süreç başlatma olayını aynı panoda görün.

Tespit için örnek sorgu mantığı

EĞER   üst süreç komut satırı "semantic_kernel" / "SemanticKernel" içeriyor
VE     alt süreç ∈ {cmd.exe, powershell.exe, bash, sh, curl, wget, certutil.exe}
O HALDE yüksek öncelikli uyarı üret

Bu mantığı EDR ürününüzün sorgu diline (KQL, SPL, Sigma) uyarlayabilirsiniz. Microsoft, Defender kullanıcıları için hazır sorgular yayımladı.

Sonuç

Semantic Kernel vakaları, ajan güvenliğinin "daha iyi istem yazmak" değil klasik yazılım güvenliği meselesi olduğunu gösteriyor: güvensiz eval, doğrulanmamış dosya yolu, gereğinden geniş bir API yüzeyi. İstem enjeksiyonunu tamamen önleyemezsiniz, ama enjeksiyon olduğunda hasarın sınırlı kalacağı bir mimari kurabilirsiniz. Bugün yapılacak en somut iş: ajanınızın her aracını listeleyin ve "model bu parametreye en kötü değeri yazarsa ne olur?" sorusunu her biri için cevaplayın.

Kaynaklar

#Prompt Injection#Semantic Kernel#CVE-2026-26030#CVE-2026-25592#AI Ajanları#RCE