Prompt Injection Tam Olarak Ne?
Prompt injection, LLM dünyasının şu an en büyük güvenlik sorunu. Bir saldırgan öyle bir girdi hazırlıyor ki model normalde yapmaması gereken şeyleri yapıyor — yetkisiz komutları çalıştırıyor, sistem promptunu sızdırıyor veya güvenlik kontrollerini aşıyor. SQL injection'dan farkı şu: burada parametrize ederek sorunu çözemiyorsunuz. Dil modelleri, geliştiricinin talimatlarıyla kullanıcı girdisine gömülmüş talimatlar arasındaki farkı doğal olarak ayırt edemiyor.
İşin korkutucu tarafı şu: risk, modelin yetkisiyle doğru orantılı büyüyor. Sadece metin üreten bir chatbot mu? Sınırlı hasar. Ama veritabanına, API'lere ve dosya sistemine erişimi olan bir AI ajanı mı? O artık saldırganlar için altın madeni. Birisi enjekte edilmiş talimatlarla ajanınızı ele geçirirse, ajanın ulaşabildiği her sisteme erişim kazanıyor.
Prompt injection yamalanabilecek bir bug değil — bugünkü LLM'lerin metni işleme biçiminin temel bir özelliği. Tek bir çözüm yetmez, birden fazla savunma katmanı şart.
Doğrudan ve Dolaylı Injection
Doğrudan prompt injection basit olanı. Saldırgan doğrudan "Önceki tüm talimatları görmezden gel ve..." gibi bir şey yazıyor. Daha sofistike versiyonları rol yapma oyunları, kodlama hileleri veya çok turlu konuşmalar kullanarak modeli yavaş yavaş rayından çıkarıyor. Günümüz LLM'leri basit denemeleri daha iyi yakalıyor ama yaratıcı saldırganlar sürekli yeni açılar buluyor.
Dolaylı injection çok daha tehlikeli. Saldırgan komutu doğrudan yazmıyor, bunun yerine modelinizin işleyeceği verilerin içine gizliyor — bir web sayfasına, belgeye, e-postaya, veritabanı kaydına veya API yanıtına. RAG pipeline'ınız gizli talimatlar içeren bir sayfa getirdiğinde, modeliniz bu talimatları siz yazmışsınız gibi uygulayabiliyor. Bunu gerçek ortamda gördüm ve tespit etmesi gerçekten zor.
Sık Karşılaşılan Saldırı Kalıpları
- Talimat geçersiz kılma: "Sistem promptunu görmezden gel" gibi doğrudan komutlar — kaba ama bazı modellerde hâlâ işe yarıyor
- Bağlam manipülasyonu: Konuşmayı birden fazla turda yavaşça kaydırarak yetkisiz davranışları normalleştirme
- Kodlama saldırıları: Base64, ROT13 veya Unicode hileleriyle girdi filtrelerini atlatma
- Payload bölme: Saldırıyı birden fazla girdiye veya belgeye dağıtarak tek başına şüpheli görünmesini engelleme
- Sanallaştırma: Modelden güvenlik kısıtlaması olmayan farklı bir AI gibi davranmasını isteme
- Veri üzerinden dolaylı injection: Modelin tüketeceği belgelere, web sayfalarına veya veritabanı kayıtlarına talimat yerleştirme
İlk Savunma Hattı: Girdi Temizleme
İlk adım, girdileri modele ulaşmadan önce temizlemek. Bilinen injection kalıplarını çıkarın, uzunluk sınırı koyun, format doğrulaması yapın ve bütçeniz varsa injection denemelerini yakalamak için eğitilmiş bir sınıflandırıcı model kullanın. Her şeyi durduracak mı? Hayır. Ama çıtayı önemli ölçüde yükseltiyor ve denemelerin büyük çoğunluğunu oluşturan düşük eforlu saldırıları filtreliyor.
class InputSanitizer:
INJECTION_PATTERNS = [
r"ignore (all |any )?(previous|prior|above) (instructions|prompts)",
r"you are now",
r"new instructions:",
r"system prompt:",
r"\[INST\]",
r"<\|im_start\|>system",
]
def sanitize(self, user_input: str) -> tuple[str, float]:
risk_score = 0.0
cleaned = user_input
for pattern in self.INJECTION_PATTERNS:
if re.search(pattern, cleaned, re.IGNORECASE):
risk_score += 0.3
cleaned = re.sub(pattern, "[FILTERED]", cleaned, flags=re.IGNORECASE)
# Length-based risk adjustment
if len(cleaned) > 5000:
risk_score += 0.1
return cleaned, min(risk_score, 1.0)Basit bir girdi temizleyici — kalıp eşleme ve risk puanlamasıyla bariz olanları yakalıyor
İkinci Katman: Çıktı Doğrulama
Pratikte bazı injection'lar girdi filtrelerinizi aşacak. Bu bir gerçek. O yüzden çıktı tarafını da kontrol etmeniz gerekiyor. Çıktıları beklenen formatlara göre kontrol edin, sızan sistem promptları veya hassas veriler için tarayın, araç çağrılarının izin verilen sınırlar içinde kaldığından emin olun ve şüpheli yanıtları işaretlemek için ayrı bir sınıflandırıcı çalıştırın. Bunu ilk savunma hattınızın kötü bir gün geçirdiği zamanlar için güvenlik ağı olarak düşünün.
Üçüncü Katman: Yetki Ayrımı
Bu kısım çok önemli ama sık göz ardı ediliyor. En az yetki ilkesini sıkı sıkıya uygulayın. Her ajan ve araç, işini yapmak için gereken minimum yetkiye sahip olsun. Kritik işlemler her zaman kullanıcı onayı gerektirsin — model ne derse desin. Ağ erişimini, dosya sistemi erişimini ve API anahtarlarını olabildiğince dar tutun. Ajanlarınızı sandbox ortamlarda çalıştırın ki ele geçirilmiş bir model tüm sistemi çökertemesin.
Hepsini Bir Araya Getirmek: Derinlemesine Savunma
Tek bir katman sizi kurtarmaz. Asıl güç her şeyi birleştirmekten geliyor — girdi temizleme, çıktı doğrulama, yetki ayrımı, izleme ve hız sınırlama. Her katman diğerlerinin kaçırdığını yakalıyor. Güvenlik duruşunuzun bir savunma başarısız olduğunda kâğıttan kale gibi çökmesini değil, kontrollü bir şekilde geri çekilmesini istiyorsunuz.
class DefenseOrchestrator:
def __init__(self):
self.input_sanitizer = InputSanitizer()
self.output_validator = OutputValidator()
self.permission_checker = PermissionChecker()
self.rate_limiter = RateLimiter(max_actions=10, window_seconds=60)
async def process_request(self, user_input: str, context: dict) -> Response:
# Layer 1: Input sanitization
cleaned_input, risk_score = self.input_sanitizer.sanitize(user_input)
if risk_score > 0.7:
return Response.blocked("Input flagged as potential injection")
# Layer 2: Rate limiting
if not self.rate_limiter.allow(context["user_id"]):
return Response.blocked("Rate limit exceeded")
# Layer 3: Generate response with constrained context
response = await self.llm.generate(cleaned_input, context)
# Layer 4: Output validation
validated = self.output_validator.validate(response, context)
if not validated.safe:
return Response.blocked("Output failed safety validation")
# Layer 5: Permission check for any tool calls
for tool_call in response.tool_calls:
if not self.permission_checker.allowed(tool_call, context):
return Response.blocked(f"Unauthorized action: {tool_call.name}")
return validated.responseTam savunma orkestratörü — beş katman birlikte çalışarak sistemi koruyor
İzleme: Gözünüz Kulağınız Olsun
Tüm bu savunmalara rağmen sistemi izlemeniz şart. Her girdiyi, çıktıyı ve araç çağrısını loglayın. Tuhaf durumlar için uyarılar kurun — alışılmadık uzunlukta girdiler, beklenmedik araç çağrıları, tek bir kullanıcıdan gelen yoğun istekler veya sızan sırlar gibi görünen çıktı kalıpları. Sisteminize devre kesiciler yerleştirin. Bir şeyler ters gittiğinde ajan yetkilerini anında iptal edip güvenli varsayılanlara dönün. Birinin fark etmesini beklemeyin.
Warning
Prompt injection tespitini LLM'in kendisine bırakmayın. Modelleri saldırıya açık yapan şey — bağlamdaki talimatları hevesle takip etmeleri — aynı zamanda onları kendi bağlamlarının ele geçirilip geçirilmediğine karar vermekte güvenilmez kılıyor.
Bundan Sonra Ne Olacak?
Saldırganlarla savunucular arasındaki kedi-fare oyunu, LLM'ler daha yetenekli hale geldikçe ve kritik sistemlere daha derinden entegre oldukça devam edecek. Umut verici araştırmalar var — LLM çıktılarının formal doğrulaması, AI iş yükleri için donanım seviyesinde izolasyon ve talimat işlemeyi veri işlemeden temelden ayıran mimariler. Ama henüz o noktada değiliz. Şimdilik derinlemesine savunma en iyi seçeneğiniz. Savunmalarınızı katmanlayın, her birinin eninde sonunda aşılacağını varsayın ve sisteminizi buna göre tasarlayın.