Mert Özen Her Satırda Daha İleri
Yapay Zeka LLM Uygulama Güvenliği — #09

OWASP LLM Top 10'un Evrimi: 2023'ten 2025'e ve 2026'ya, Agentic Top 10 ve Agent Control Standard

Mert Özen 14 Kas 2026 16 dk 1 görüntülenme
OWASP LLM Top 10'un Evrimi: 2023'ten 2025'e ve 2026'ya, Agentic Top 10 ve Agent Control Standard

OWASP LLM Top 10'da aynı ID üç sürümde üç ayrı riski gösterebilir: 2023'ün LLM06'sı hassas bilgi ifşasıydı, 2026'nınki Unbounded Consumption. 2023, 2025 ve 2026 listelerini konuya göre hizalıyor, dağılan ve eklenen maddeleri, 2026 sıra hareketlerini, Agentic Top 10'u ve Agent Control Standard'ı ele alıyor, eski bir sızma testi raporunu 2026 ID'lerine taşıyan bir C# aracı yazıyoruz.

Sürüm notu: Bu yazıdaki kodlar .NET 10 ile derlenip denenmiştir. Karşılaştırılan listeler OWASP (web uygulama güvenliği üzerine çalışan açık topluluk) Top 10 for LLM (büyük dil modeli) Applications v1.1 (16 Ekim 2023), 2025 sürümü (18 Kasım 2024) ve 2026 sürümü (3 Ağustos 2026) ile OWASP Top 10 for Agentic Applications 2026'dır (9 Aralık 2025).

Önce Tahmin Et

Bookstore'a 2024 baharında bir güvenlik firması sızma testi yapmış. Rapordaki bulgulardan biri "LLM06: Sensitive Information Disclosure — personel indirim kodu system prompt'ta duruyor". Bugün bir sprint toplantısında biri şöyle diyor: "LLM06 için bütçe ve rate limit'i geçen ay bitirdik, o madde kapandı." İkisi aynı LLM06 mı? Aynı rapordaki "LLM07: Insecure Plugin Design" bulgusu bugünkü listede hangi maddeye karşılık geliyor?

Cevap: ikisi farklı LLM06'lar ve LLM07'nin bugün tek bir karşılığı yok. 2023'te LLM06 hassas bilgi ifşasıydı, 2026'da LLM06 Unbounded Consumption. Aynı kimlik numarası üç sürümde üç ayrı şeyi gösterebiliyor. Bu serinin son yazısında listenin nasıl değiştiğine bakıyor, değişikliklerin bir uygulama ekibi için ne anlama geldiğini çıkarıyor ve eski bir raporu bugünün ID'leriyle okuyan küçük bir araç yazıyoruz.

Üç Sürüm, Tek Tabloda

İlk sürüm 1 Ağustos 2023'te çıktı, birkaç ay sonra 1.1 ile güncellendi. 2025 sürümü 18 Kasım 2024'te, 2026 sürümü 3 Ağustos 2026'da yayımlandı. Aşağıdaki tablo maddeleri numaraya göre değil konuya göre hizalıyor; numarayla hizalamak, açılıştaki karışıklığın kendisi olurdu:

Konu2023 (v1.1)20252026
Prompt injectionLLM01 Prompt InjectionLLM01 Prompt InjectionLLM01 Prompt Injection
Hassas bilgi ifşasıLLM06 Sensitive Information DisclosureLLM02 Sensitive Information DisclosureLLM02 Sensitive Information Disclosure
Fazla yetki ve otonomiLLM08 Excessive AgencyLLM06 Excessive AgencyLLM03 Excessive Agency
Tedarik zinciriLLM05 Supply Chain VulnerabilitiesLLM03 Supply ChainLLM04 Supply Chain
Veri ve model zehirlemeLLM03 Training Data PoisoningLLM04 Data and Model PoisoningLLM05 Data and Model Poisoning
Kaynak ve maliyet tüketimiLLM04 Model Denial of ServiceLLM10 Unbounded ConsumptionLLM06 Unbounded Consumption
Yanlış bilgi ve aşırı güvenLLM09 OverrelianceLLM09 MisinformationLLM07 Misinformation
Gizli contextyokLLM07 System Prompt LeakageLLM08 Hidden Context Exposure
Vector ve embeddingyokLLM08 Vector and Embedding WeaknessesLLM09 Vector and Embedding Weaknesses
Çıktının işlenmesiLLM02 Insecure Output HandlingLLM05 Improper Output HandlingLLM10 Improper Output Handling
Plugin tasarımıLLM07 Insecure Plugin Designayrı madde yokayrı madde yok
Model hırsızlığıLLM10 Model TheftUnbounded Consumption içindeLLM06 içinde; yan kanal LLM02'de

Tablonun özeti: prompt injection hiç yerinden oynamadı, iki madde (plugin tasarımı ve model hırsızlığı) ayrı madde olmaktan çıktı, iki yeni konu (gizli context ve vector store) eklendi, geri kalan altı konu hem ad hem sıra değiştirdi. Listenin özetini Web Güvenliği (OWASP Top 10) serisinin 21. yazısında 2025 sürümü üzerinden yapmıştık; burada maddeleri tek tek değil, değişimin kendisini okuyoruz.

2023'ten 2025'e: Ne Dağıldı, Ne Geldi?

2025 sürümünün proje liderlerinden gelen önsözü dört değişikliği öne çıkarıyor. Model Denial of Service, kaynak yönetimi ve beklenmedik maliyetleri de kapsayacak şekilde genişleyip Unbounded Consumption oldu; 7. yazıdaki denial of wallet ve token bütçesi bu genişlemenin ürünü. Topluluğun RAG (cevap üretmeden önce ilgili belgeleri bulup modele veren yaklaşım) ve embedding tabanlı yöntemler için rehber istemesi üzerine Vector and Embedding Weaknesses eklendi. Gerçek istismarlar görüldüğü için System Prompt Leakage ayrı bir madde oldu; önsözün vurgusu, prompt'taki bilginin gizli kalacağını varsaymanın güvenli olmadığı. Excessive Agency de agent mimarilerinin yaygınlaşmasıyla genişletildi.

Önsözün söylemediği ama madde metinlerinden okunan iki değişiklik daha var. 2023'ün Insecure Plugin Design maddesi 2025'te ayrı bir başlık olarak yok; 2025'in Excessive Agency metni gereğinden fazla fonksiyon taşıyan ve gereğinden fazla yetkiyle çalışan "extension"ları (tool, skill ya da plugin) tam olarak bu konunun içinde anlatıyor, Improper Output Handling metni de üçüncü taraf extension'ların input'u doğrulamamasını risk örneği olarak sayıyor. Yani plugin bir varlık türü olmaktan çıkıp iki farklı hatanın taşıyıcısı olarak ele alınıyor. 2023'ün Overreliance maddesi de Misinformation'ın içinde, onu büyüten ilgili bir sorun olarak tartışılıyor. Model Theft'in API üzerinden yapılan kısmı (model extraction, işlevsel kopya üretmek) Unbounded Consumption'ın risk örneklerine girmiş.

Bu kaymaların ortak bir yönü var: 2023 listesi daha çok bileşen türlerine (plugin, model, eğitim verisi) göre düşünürken, 2025 listesi hatalara ve etkilerine göre düşünüyor. Bir uygulama ekibi için pratik sonucu şu: 2023'te "plugin'imiz yok, LLM07 bizi ilgilendirmez" diyen bir ekibin bugün tool çağıran bir asistanı varsa, aynı risk Excessive Agency başlığında karşısında.

2025'ten 2026'ya: Sıra Hareketleri ve Olay Verisi

2026 sürümünde madde adları büyük ölçüde aynı kaldı, ama sıra önceki sürümlerden daha fazla oynadı. Hareketlerin hepsini tablodan okuyabilirsin; dokümanın gerekçe verdiği başlıcaları şunlar. Excessive Agency altıncıdan üçüncüye çıktı; dokümana göre listedeki en önemli hareket bu ve gerekçe, hem uygulayıcı oylamasının hem de olay kaydının zararın agent'lı kurulumlarda ortaya çıktığı konusunda anlaşması. Unbounded Consumption dört basamak çıktı; bu hareketi taşıyan, kaynak ve maliyet tükenmesine eskisinden daha fazla ağırlık veren uygulayıcıların oyları. Improper Output Handling en çok düşen madde oldu, beşinciden onuncuya. Misinformation dokuzdan yediye çıktı. System Prompt Leakage daha geniş bir çerçeveyle Hidden Context Exposure adını aldı: system prompt'un yanında tool şemaları ve retrieval'dan gelen gizli metin de artık aynı maddede. Bunu 3. yazıda Bookstore'un context'inin tamamını okuyarak işlemiştik.

Sırayla birlikte kapsamlar da büyüdü. Prompt Injection artık görsel ve ses içine gizlenen talimatları açıkça kapsıyor (2. yazıdaki kapak görseli deneyi). Supply Chain, terfi ettirilen bir model artifact'ının iddia ettiği şey olmaması durumunu içine aldı (6. yazıdaki registry'de taşınan tag). Data and Model Poisoning, fine-tuning'in kötüye kullanılmasını; Improper Output Handling da kod asistanlarının ölçekte ürettiği güvensiz kodu kapsıyor.

2026'nın asıl yöntem değişikliğini 1. yazıda anlatmıştık: liste ilk kez gerçek olay verisiyle sınandı, 7.714 olaydan sınıflandırılabilen 6.639'u kullanıldı ve nihai sırada uygulayıcı oylaması dörtte üç, olay verisi dörtte bir ağırlık taşıdı. Burada bunun okuma biçimine etkisine bakalım. İki sıranın ayrıştığı yerler en öğretici olanlar. Prompt injection yalnız olay sayısına göre ilk ona girmiyor ama oylamayla birinci kalıyor; dokümanın açıklaması, iyi savunulan bir riskin kamuya açık veritabanlarında az görünmesi. Misinformation ise ters yönde: oylamada sona yakın, olay kaydında başa yakın; doküman bunu, akıcı ve kendinden emin bir cevabın bir karara ya da tool çağrısına dönüştüğünde yanlış cevabın yanlış eyleme dönüşmesiyle açıklıyor. 5. yazıda kaynak numarası doğru ama iddiası yanlış cevaplar ve 6. yazıda "kayıtlarımıza göre" diyen asistan bu cümlenin küçük örnekleriydi. Bu yüzden 2026 sırasını "en tehlikeliden en az tehlikeliye" diye değil, "topluluğun kaygısı ile olayların kesiştiği yer" diye okumak daha doğru.

Agentic Top 10: Model Bir Aktör Olduğunda

2026 dokümanı iki listenin sınırını açıkça çiziyor: model uygulamanın içinde bir bileşen olduğunda risk LLM Top 10'un, tool çağıran, oturumlar arasında memory taşıyan ve downstream'de sonuç doğuran bir aktör olduğunda ise 9 Aralık 2025'te açıklanan OWASP Top 10 for Agentic Applications'ın, yani ASI (OWASP'ın agentic uygulama güvenliği çalışması) listesinin konusu. On madde ve her birinin bu serideki karşılığı:

  • ASI01 Agent Goal Hijack: dışarıdan gelen içeriğin agent'ın amacını değiştirmesi; 1. ve 2. yazıdaki canary'ler.
  • ASI02 Tool Misuse & Exploitation: tool'un amacı dışında ya da fazla fonksiyonla kullanılması; 4. yazıdaki manage_orders'ın daraltılması ve 7. yazıdaki döngüler.
  • ASI03 Identity & Privilege Abuse: agent'ın fazla yetkili ya da başkasına ait bir kimlikle iş görmesi; 4. yazıdaki servis hesabı ve kullanıcı token'ı.
  • ASI04 Agentic Supply Chain Vulnerabilities: agent'ın kullandığı tool, MCP (Model Context Protocol; AI modellerini tool'lara ve veri kaynaklarına bağlayan protokol) server ve registry'lerin tedarik zinciri; 6. yazıdaki tool tanımı lock'u.
  • ASI05 Unexpected Code Execution (RCE, Remote Code Execution): model çıktısının ya da tool'un beklenmedik şekilde kod çalıştırması; 5. yazıdaki "model SQL yazmasın" kuralı.
  • ASI06 Memory & Context Poisoning: kalıcı memory'nin ve context'in zehirlenmesi; 6. yazıdaki ingestion kapısının agent memory'deki karşılığı.
  • ASI07 Insecure Inter-Agent Communication: agent'lar arası mesajlaşmada kimlik ve yetki kapsamının korunmaması.
  • ASI08 Cascading Failures: tek bir hatanın tool ve agent zinciri boyunca büyümesi; 4. ve 7. yazıdaki bütçe ve devre kesiciler.
  • ASI09 Human-Agent Trust Exploitation: insanın onayının ya da güveninin istismar edilmesi; 4. yazıdaki onay yorgunluğu.
  • ASI10 Rogue Agents: amacından sapmış, görevi tamamlamış gibi davranan ya da kanıt uyduran agent'lar.

2026 dokümanının Ek A'sı her LLM maddesini ilgili ASI maddelerine eşliyor ve bu eşleme iki listenin nasıl birlikte okunacağını gösteriyor. Excessive Agency neredeyse bütün ASI listesine dokunuyor: ASI02 ve ASI03 onun doğrudan görünümleri, ASI08 ise rate limit ve devre kesicilerle durdurulan sonucu. Unbounded Consumption ASI02 ve ASI08'e, tek bir isteğin MCP tool çağrılarıyla çoğalması üzerinden bağlanıyor. Supply Chain ise agent'a özgü tedarik zinciri risklerini kendi kapsamından çıkarıp açıkça ASI04'e bırakıyor. Aynı ekte OWASP GenAI Data Security 2026 (DSGAI, 17 Mart 2026) listesine, MITRE ATLAS (MITRE'nin AI sistemlerine yönelik saldırı teknikleri kataloğu), CWE (yazılım zayıflık türlerinin standart listesi) ve NIST (ABD'nin ulusal standartlar ve teknoloji enstitüsü) belgelerine eşlemeler de var; bir bulguyu kurumun kullandığı başka bir çerçeveye taşırken başlanacak yer orası.

Agent Control Standard: Listeden Runtime'a

Top 10 listeleri birer risk taksonomisi; ne olabileceğini ve neye bakılacağını söylüyorlar. 1 Eylül 2026'da OWASP GenAI Security Project'in parçası olan Agent Control Standard (ACS) başka bir şey: OWASP'ın sayfasına göre agent platformlarının middleware hook'larını nasıl açacağını ve güvenlik politikalarının bu hook'lar üzerinden nasıl uygulanacağını tanımlayan bir standart. Hedef, agent framework'leri arasında taşınabilen ve runtime'da uygulanan bildirimsel (declarative) kontroller. OWASP'ın sayfası bir sürüm numarası vermiyor; standardı geliştiren ekosistemdeki kaynaklar ilk herkese açık sürümü 0.1 olarak anıyor, yani erken bir aşamada.

Bu fikir bu serinin okuruna tanıdık gelmeli. 4. yazıda her tool çağrısını FunctionInvoker delegate'inde durdurup bütçeye ve audit trail'e bağladık, 7. yazıda aynı noktaya loop guard'ı koyduk, 8. yazıda guardrail'leri IChatClient pipeline'ına middleware olarak yerleştirdik. Hepsi, bir eylem gerçekleşmeden önce durup bir politikaya sormanın Bookstore'a özel uygulamalarıydı. ACS'nin amacı bu hook noktalarını ve politika kararlarını framework'ten bağımsız, standart bir biçime kavuşturmak. Bugün için pratik önerim şu: kontrollerini yine bu seride olduğu gibi kendi kodunda, açık hook noktalarında tut; standart olgunlaştıkça o hook'ları ACS'nin tarif ettiği biçime bağlamak, kontrolleri her yere dağıtmış bir koddan çok daha kolay olur.

Eski Bir Raporu Bugünün ID'leriyle Okumak

Açılıştaki soruna dönelim. Bookstore'un risk kaydında 2024'ten kalma, 2023 ID'leriyle etiketlenmiş bulgular ve 2025 ID'siyle etiketlenmiş daha yeni bir bulgu var. Bunları 2026 listesine taşıyan küçük bir eşleme yazdım. Eşleme iki adımlı: 2023'ten 2025'e, oradan 2026'ya. Böylece yeni bir sürüm çıktığında yalnız son adımı eklemek yetiyor:

public sealed record Mapping(string[] Targets, string? Note = null);

// Eski bir rapordaki madde ID'sini 2026 listesine taşır; bire bir karşılığı olmayanlar not taşır
public static class OwaspLlmMap
{
    public static readonly Dictionary<string, string> Names2026 = new()
    {
        ["LLM01:2026"] = "Prompt Injection",
        ["LLM02:2026"] = "Sensitive Information Disclosure",
        ["LLM03:2026"] = "Excessive Agency",
        ["LLM04:2026"] = "Supply Chain",
        ["LLM05:2026"] = "Data and Model Poisoning",
        ["LLM06:2026"] = "Unbounded Consumption",
        ["LLM07:2026"] = "Misinformation",
        ["LLM08:2026"] = "Hidden Context Exposure",
        ["LLM09:2026"] = "Vector and Embedding Weaknesses",
        ["LLM10:2026"] = "Improper Output Handling",
    };

    // 2025 -> 2026: adlar aynı kaldı, yalnız sıra değişti; System Prompt Leakage genişleyip yeniden adlandırıldı
    private static readonly Dictionary<string, Mapping> From2025 = new()
    {
        ["LLM01:2025"] = new(["LLM01:2026"]),
        ["LLM02:2025"] = new(["LLM02:2026"]),
        ["LLM03:2025"] = new(["LLM04:2026"]),
        ["LLM04:2025"] = new(["LLM05:2026"]),
        ["LLM05:2025"] = new(["LLM10:2026"]),
        ["LLM06:2025"] = new(["LLM03:2026"]),
        ["LLM07:2025"] = new(["LLM08:2026"], "System Prompt Leakage widened into Hidden Context Exposure"),
        ["LLM08:2025"] = new(["LLM09:2026"]),
        ["LLM09:2025"] = new(["LLM07:2026"]),
        ["LLM10:2025"] = new(["LLM06:2026"]),
    };

    // 2023 (v1.1) -> 2025: adlar ve kapsamlar değişti, iki madde dağıldı
    private static readonly Dictionary<string, Mapping> From2023 = new()
    {
        ["LLM01"] = new(["LLM01:2025"]),
        ["LLM02"] = new(["LLM05:2025"], "Insecure Output Handling renamed Improper Output Handling"),
        ["LLM03"] = new(["LLM04:2025"], "Training Data Poisoning widened to Data and Model Poisoning"),
        ["LLM04"] = new(["LLM10:2025"], "Model Denial of Service widened to Unbounded Consumption"),
        ["LLM05"] = new(["LLM03:2025"]),
        ["LLM06"] = new(["LLM02:2025"]),
        ["LLM07"] = new(["LLM06:2025", "LLM05:2025"], "Insecure Plugin Design has no successor: review as agency or output handling"),
        ["LLM08"] = new(["LLM06:2025"]),
        ["LLM09"] = new(["LLM09:2025"], "Overreliance is now discussed under Misinformation"),
        ["LLM10"] = new(["LLM10:2025"], "Model Theft via API extraction moved to Unbounded Consumption"),
    };

    public static Mapping To2026(string id)
    {
        if (From2025.TryGetValue(id, out Mapping? direct))
        {
            return direct;
        }

        if (From2023.TryGetValue(id, out Mapping? old))
        {
            string[] targets = [.. old.Targets.SelectMany(t => From2025[t].Targets).Distinct()];
            return new(targets, old.Note);
        }

        throw new ArgumentException($"Unknown OWASP LLM ID: {id}", nameof(id));
    }
}
using System.Text.Json;
using Bookstore.Security.OwaspMap;

List<Finding> findings = JsonSerializer.Deserialize<List<Finding>>(File.ReadAllText(args[0]), JsonSerializerOptions.Web)!;

foreach (Finding f in findings)
{
    Mapping m = OwaspLlmMap.To2026(f.Owasp);
    string targets = string.Join(" + ", m.Targets.Select(t => $"{t} {OwaspLlmMap.Names2026[t]}"));
    Console.WriteLine($"{f.Id}  {f.Owasp,-10} -> {targets}");
    Console.WriteLine($"      {f.Title}");

    // ID eşlemesi mekanik; anlam kaymasını yakalamak için başlığa da bak
    if (f.Title.Contains("system prompt", StringComparison.OrdinalIgnoreCase) && !m.Targets.Contains("LLM08:2026"))
    {
        Console.WriteLine("      review: system prompt contents now have their own entry, LLM08:2026 Hidden Context Exposure");
    }

    if (m.Note is not null)
    {
        Console.WriteLine($"      note: {m.Note}");
    }
}

public sealed record Finding(string Id, string Owasp, string Title);
[
  { "id": "F-01", "owasp": "LLM02", "title": "Chat widget renders model output as raw HTML" },
  { "id": "F-02", "owasp": "LLM07", "title": "Order plugin accepts a free-form SQL filter from the model" },
  { "id": "F-03", "owasp": "LLM04", "title": "No limit on message size or requests per user" },
  { "id": "F-04", "owasp": "LLM06", "title": "Staff discount code stored in the system prompt" },
  { "id": "F-05", "owasp": "LLM09", "title": "Support team copies assistant refund answers without checking" },
  { "id": "F-06", "owasp": "LLM10", "title": "Public API returns token log-probabilities" },
  { "id": "F-07", "owasp": "LLM07:2025", "title": "Assistant repeats its system prompt when asked" }
]

2023 sürümü ID'leri yılsız yazıyordu (LLM01, LLM02); 2025'ten itibaren ID'ler yılı da taşıyor. Kod bu farkı kullanarak hangi sürümün ID'siyle karşılaştığını anlıyor:

$ dotnet run -- report-2024.json
F-01  LLM02      -> LLM10:2026 Improper Output Handling
      Chat widget renders model output as raw HTML
      note: Insecure Output Handling renamed Improper Output Handling
F-02  LLM07      -> LLM03:2026 Excessive Agency + LLM10:2026 Improper Output Handling
      Order plugin accepts a free-form SQL filter from the model
      note: Insecure Plugin Design has no successor: review as agency or output handling
F-03  LLM04      -> LLM06:2026 Unbounded Consumption
      No limit on message size or requests per user
      note: Model Denial of Service widened to Unbounded Consumption
F-04  LLM06      -> LLM02:2026 Sensitive Information Disclosure
      Staff discount code stored in the system prompt
      review: system prompt contents now have their own entry, LLM08:2026 Hidden Context Exposure
F-05  LLM09      -> LLM07:2026 Misinformation
      Support team copies assistant refund answers without checking
      note: Overreliance is now discussed under Misinformation
F-06  LLM10      -> LLM06:2026 Unbounded Consumption
      Public API returns token log-probabilities
      note: Model Theft via API extraction moved to Unbounded Consumption
F-07  LLM07:2025 -> LLM08:2026 Hidden Context Exposure
      Assistant repeats its system prompt when asked
      note: System Prompt Leakage widened into Hidden Context Exposure

Çıktıda üç tür satır var. Mekanik olarak taşınanlar (F-01, F-03, F-07) ve not taşıyanlar sorunsuz. F-02, yani eski Insecure Plugin Design bulgusu, iki maddeye düşüyor ve bir insanın karar vermesi gerekiyor; serbest SQL kabul eden bir plugin hem fazla fonksiyon (Excessive Agency) hem de doğrulanmamış çıktı (Improper Output Handling) sorunu, ve 5. yazıdaki gibi izinli sorgu şablonları ikisini birden kapatıyor. En öğretici satır F-04: 2023'te system prompt'taki indirim kodu bir hassas bilgi ifşasıydı ve ID eşlemesi onu doğru şekilde LLM02:2026'ya taşıyor. Ama bugün aynı bulgunun daha doğru yeri, system prompt içeriği için açılmış ayrı madde, LLM08:2026. ID eşlemesi bunu bilemez; bu yüzden kod başlığa da bakıp bir "review" satırı ekliyor. Buradan çıkan genel sonuç: bir listenin sürümleri arasında ID'yi mekanik olarak taşımak bir başlangıç, karar değil. Her taşınan bulguyu yeni maddenin metniyle bir kez okumak gerekiyor.

Bu Seri Nasıl Güncellenecek?

OWASP listeleri yaklaşık yılda bir güncelleniyor ve bu seri 2026 sürümüne göre yazıldı. Bir sonraki sürüm çıktığında yapılacakların listesi şimdiden belli. İlk iş eşleme tablosu: yukarıdaki koda yeni sürüm için bir sözlük eklemek ve bu yazıdaki tabloya bir sütun eklemek. Sonra 1. yazıdaki madde-yazı haritası: yeniden numaralanan maddeler için hangi yazının hangi maddeyi işlediği güncellenecek; yazıların içeriği maddenin numarasına değil konusuna bağlı olduğu için metnin büyük kısmı değişmeden kalacak. Üçüncüsü ölçümler: bu serideki deneyler belirli model sürümleriyle koşuldu (gemma3:4b, gemma3:12b, qwen3:4b, Ollama 0.34.4) ve 6. yazıda gördüğümüz gibi aynı tag zamanla başka bir artifact'ı gösterebiliyor. Yeni sürümde PINEAPPLE canary'si, sızan indirim kodu, kampanya yorumları ve 8. yazıdaki red team seti yeniden koşulacak, sayılar değiştiyse metin gerçek sonuca göre düzeltilecek. Son olarak sürüm notları: her yazının ilk satırı hangi liste sürümüne ve hangi paket sürümlerine göre yazıldığını söylüyor; güncellenen yazının notu da güncellenecek.

Kendi ekibin için de aynı süreç geçerli. Risk kaydında OWASP ID'sini her zaman yılıyla yaz (LLM06 değil, LLM06:2026), her bulguya listeden bağımsız kendi iç kimliğini ver ve liste değiştiğinde yalnız etiketi güncelle. Bulgunun kendisi, kanıtı ve kapanış testi aynı kalır.

Üretimde Dikkat

Liste sürümünü sözleşmelere ve politikalara sabitle. "Uygulama OWASP LLM Top 10'a uygun olmalıdır" cümlesi, hangi sürüm olduğunu söylemiyorsa denetimde tartışma çıkarır. "OWASP Top 10 for LLM Applications 2026" yaz ve bir sonraki sürüme geçişi bir karar olarak al.

Eşleme tablosunu kod gibi yönet. Yukarıdaki gibi bir eşleme, birim testleriyle birlikte repoda dursun; yeni bir sürüm geldiğinde değişiklik bir PR olsun ve güvenlik ekibi review etsin. Tablonun bir wiki sayfasında durması, iki yıl sonra kimsenin hangi satırın neden öyle olduğunu hatırlamaması demek.

Listeyi bir kontrol listesi değil bir başlangıç noktası say. 1. yazıda söylediğimiz gibi, OWASP sırası topluluğun genel bir sıralaması; senin ürününün risk sırası tehdit modelinden çıkar. Ödeme tool'u olmayan bir asistanda Excessive Agency'nin üçüncü sırada olması seni bağlamaz, kullanıcıların yüklediği PDF'leri işleyen bir sistemde Data and Model Poisoning onuncu sırada olsa bile önceliklidir.

Sık Düşülen Tuzaklar

Birincisi, ID'yi yılsız kullanmak. "LLM06" bugün üç farklı şey demek olabilir; açılıştaki toplantıda iki kişi aynı kelimeyle iki ayrı riskten konuşuyordu.

İkincisi, kaybolan maddeyi kapanmış sanmak. Insecure Plugin Design ve Model Theft listede ayrı madde olarak yok ama riskler yerinde duruyor; yalnız başka başlıkların altına taşındılar. Eski bir rapordaki bu bulguları "artık listede yok" diye kapatmak, açık bir bulguyu kayıttan silmek demek.

Üçüncüsü, sıradaki düşüşü riskin azalması diye okumak. Improper Output Handling beşinciden onuncuya düştü; bu, Markdown render'ındaki ya da SQL'deki bir açığın daha az tehlikeli olduğu anlamına gelmiyor. Doküman bu sıranın oylama ve olay verisinin birleşiminden çıktığını açıkça söylüyor; düşüş, iyi bilinen ve savunulan bir riskin topluluk gündeminde gerilemesi.

Dördüncüsü, iki listeden birini okuyup diğerini atlamak. Tool çağıran bir asistanın riskleri LLM Top 10 ile Agentic Top 10'un kesişiminde; Ek A'daki eşleme bu yüzden var.

Küçük Bir Deneme

★☆☆ OwaspLlmMap için bir xUnit testi yaz: 2025 listesinin on ID'sinin her biri 2026'da tam olarak bir maddeye gitsin ve hiçbir 2026 maddesi iki kez hedef olmasın. Aynı testi 2023 için yazdığında hangi satırlar bu kuralı bozuyor ve neden?

★★☆ Eşlemeye ASI ipuçları ekle: 2026'da LLM03, LLM04 ya da LLM06'ya düşen bir bulgu için, bulgu başlığında "tool", "agent" ya da "MCP" geçiyorsa Ek A'daki ilgili ASI maddelerini de öneren bir satır yazdır.

★★★ Kendi ekibinin (ya da Bookstore'un) risk kaydını bu seriye göre baştan yaz: her bulgu için iç kimlik, 2026 LLM ID'si, varsa ASI ID'si, kanıt ve kapanış testi. Kapanış testlerinin kaçı 8. yazıdaki gibi CI'da koşan bir regresyon testine dönüştürülebiliyor? Dönüştürülemeyenler için ne yapacaksın?

Seri burada bitiyor: bir tehdit modeliyle başladık, OWASP'ın on maddesini Bookstore.Assistant'ın parçalarında tek tek ele aldık, hepsini bir guardrail pipeline'ında ve bir regresyon setinde birleştirdik. Bundan sonrası iki komşu seride: AI Destekli Geliştirme serisi kod asistanlarını güvenle kullanmayı, Angular ile AI Arayüzleri serisi de chat arayüzünün streaming ve kullanıcı deneyimi tarafını ele alacak; çıktı render'ının güvenliği için ikisi de 5. yazıya dönecek.