Prompt Injection İçin Test Yazdım: Saldırı Başarılı Oldu Ama Test Yeşil Yandı!

İçindekiler
Bir yapay zekâ projesinde güvenlik testlerinizin %100 başarıyla geçmesi, sisteminizin gerçekten korunduğu anlamına gelir mi? Açık kaynaklı llm-council aracının geliştiricisi Marco'nun yaşadığı vaka; LLM tabanlı mimarilerde test tasarımı, kod kapsamı (coverage) yanılsaması ve güvenlik üzerine hayati dersler içeriyor.
1. Savunulan Yapı: LLM Zincirlerinde Prompt Enjeksiyonu
Büyük dil modellerinin birbirinin çıktısını girdi olarak aldığı çok aşamalı mimarilerde, güvenilmeyen model çıktıları doğrudan bir sonraki prompt'a aktarılır. Bu durum OWASP LLM01 (Prompt Injection) açığına zemin hazırlar. Standart savunma yöntemi, güvenilmeyen içeriği <<<RESPONSE_A_BEGIN>>> ve <<<RESPONSE_A_END>>> gibi sınır etiketleriyle (fencing) sarmalamaktır. Ancak bu etiketler açık kaynak kodda sabit tanımlandığında, saldırgan kendi yanıtının içerisine kapanış etiketini yazarak bloğu erkenden kapatabilir. Model, bu etiketten sonraki kısmı sistem komutu sanarak çalıştırır. Kısacası sabit etiketli bir çit, anahtarı üzerinde bırakılmış bir kapıdan farksızdır.
2. Asla Başarısız Olmayan Yanıltıcı Testler
Geliştirici bu saldırıyı engellemek için önceden bir birim testi yazmıştı ve test yeşil yanıyordu. Ancak testin ismi "bir kullanıcı sahte sınır oluşturamaz" iddiasını taşırken, testin assert ifadesi yalnızca Python dizesindeki etiket sayısını ve indeks sırasını kontrol ediyordu. Yani test, asıl güvenlik özelliğini ("model aldatılabilir mi?") değil, yalnızca metin birleştirmeyi doğrulamıştı. %100 kod kapsamına rağmen, testin ismi ile doğruladığı mantık birbirinden tamamen kopmuştu.
3. Çözüm: Kriptografik Nonce ile Dinamik Çitleme
Savunma mekanizması etiketlerin biçiminden değil, saldırganın tahmin edemeyeceği dinamik değerlerden gelmelidir:
- Kriptografik Rastgelelik: Python'un tahmin edilebilir
randommodülü yerinesecrets.token_hex()kullanılarak her çalıştırmada tekil bir nonce üretildi (<<<{label}_{nonce}_END>>>). - Doğru İddia (Assertion): Testler, metinde sahte etiket olup olmadığını değil; yalnızca sistemin ürettiği geçerli nonce'a sahip etiketlerin tanındığını denetleyecek şekilde güncellendi.
- Mutasyon Testi Doğrulaması: Kasıtlı olarak sabit nonce'a dönüldüğünde testlerin kırmızıya dönmesi sağlanarak düzeltme doğrulandı.
4. Beklenmeyen Engel: Kalite Kapılarını Devre Dışı Bırakmamak
Yeni test çekme isteğinde (PR) SonarCloud kalite kapısına takıldı. İlk refleks kuralı devre dışı bırakmak (suppression) olsa da, statik analiz aracının haklı bir zafiyete işaret ettiği anlaşıldı: İki ardışık çağrıyı karşılaştırmak zayıf bir rastgelelik testidir. Kuralı esnetmek yerine 50 farklı çağrının benzersizliğini doğrulayan daha sağlam bir test yazıldı.
5. Yazılım Geliştiriciler İçin Pratik Çıkarımlar
- Test Kapsamına Körlemesine Güvenmeyin: %100 test coverage, doğru şeyleri test ettiğinizi garanti etmez. Testin adı ile
assertmantığı arasındaki anlamsal uyumu mutlaka denetleyin. - Mutasyon Testi (Mutation Testing) Kullanın: Kodu bilerek bozun; testleriniz kırmızıya dönmüyorsa aslında hiçbir şeyi korumuyorlardır.
- LLM İzolasyonunda Dinamik Değerler Kullanın: Dışarıdan gelen verileri modeller arasında taşırken asla statik etiketler kullanmayın; çalışma zamanında tekil nonceler ekleyin.
- Linter ve Kalite Araçlarına Kulak Verin: Kalite araçlarını susturmak yerine test kalitenizi artırın.
Orijinal makaleye buradan ulaşabilirsiniz.
Bu konuyu daha derinlemesine öğrenmek ister misin?
Edumints'teki ücretsiz kursları incele ve bugün başla.
Kurslara Göz At →