LLM Security · How-To · 4 Ağustos 2026

OWASP LLM Top 10 2026'yı CI'ınıza Gömün
Makine-Okunur Veri Seti (JSON) ile Kapsam Karnesi

OWASP LLM Top 10 2026 sadece okunacak bir liste değil; makine-okunur bir JSON veri seti. Bu rehber, listeyi CI hattınıza, tarayıcı bulgularınıza ve kapsam karnenize nasıl gömeceğinizi somut kod örnekleriyle gösterir.

30 saniyede özet

  • OWASP LLM Top 10 2026 (yayın: 4 Ağustos 2026) bir belge olmasının yanında açık bir JSON veri seti olarak da mevcut: data/llm-top10-2026.json — GitHub ve Hugging Face üzerinde.
  • Her kayıt şu alanları taşır: id, en_title, tr_title, en_summary, tr_summary, prev_2025_id, change, change_note.
  • Python'da tek çağrıyla yükleyin; tarayıcı/pentest bulgularınızı LLM01:2026..LLM10:2026 kanonik kimliklerine eşleyin.
  • prev_2025_id alanı 2025→2026 yeniden eşlemesini taşır; eski referanslar (ör. LLM05:2025) çözülmeye devam eder.
  • CI'da iki bağımsız kapı kurun: kapsam karnesi (test paketiniz 10 kategoriye dokunuyor mu) ve bulgu kapısı (eşik üstü açık bulguda build düşer).
  • Dürüstlük notu: İngilizce kimlik ve başlıklar resmî; Türkçe çeviri topluluk katkısıdır (gayriresmî). Lisans CC BY-SA 4.0.

Veri seti: alanlar, kaynak ve lisans

Amaç, listeyi kopyala-yapıştır bir tabloya sıkıştırmak değil; onu boru hattınızda sorgulanabilir bir veri kaynağına dönüştürmek. Veri seti düz bir dizi olup her öğe tek bir 2026 kategorisidir. Alanlar şunlardır:

AlanTürAçıklama
idstringKanonik 2026 kimliği, ör. LLM03:2026
en_titlestringResmî İngilizce başlık
tr_titlestringGayriresmî Türkçe başlık
en_summarystringKısa İngilizce özet
tr_summarystringKısa Türkçe özet
prev_2025_idstring / null2025 listesindeki karşılığı (yeni giriş ise boş)
changestringDeğişim yönü (ör. unchanged, up, down, renamed)
change_notestringSıra/kapsam değişiminin kısa gerekçesi

Dürüstlük ve lisans: İngilizce id ve en_title değerleri OWASP GenAI Security Project'in resmî 2026 belgesinden gelir ve normatif kabul edilmelidir. tr_title/tr_summary ise gayriresmî topluluk çevirisidir; yasal veya sözleşmesel metinlerde İngilizce kimliği esas alın. Veri seti CC BY-SA 4.0 ile dağıtılır: türetdiğiniz karne ve dashboard'ları da atıf vererek ve aynı lisansla (ShareAlike) paylaşmanız gerekir.

Python ile yükleme

İki yol var. GitHub'dan ham JSON çekmek, boru hattınıza sabit bir dosya bağımlılığı ekler:

import json, urllib.request

RAW = ("https://raw.githubusercontent.com/"
       "fevziegeyurtsevenler/owasp-llm-top10-2026-tr/main/data/llm-top10-2026.json")

with urllib.request.urlopen(RAW) as r:
    items = json.load(r)

by_id = {x["id"]: x for x in items}

for x in items:
    print(x["id"], x["en_title"], "—", x["tr_title"], f"({x['change']})")

Alternatif olarak Hugging Face veri setini datasets ile yükleyebilirsiniz — versiyonlama ve cache'i onlara bırakırsınız:

from datasets import load_dataset

ds = load_dataset("fevziegeyurtsevenler/owasp-llm-top10-2026-tr", split="train")
by_id = {row["id"]: row for row in ds}

Her iki durumda da elinizde by_id sözlüğü olur; kanonik kimlikten başlığa ve özete doğrudan erişirsiniz.

2025 → 2026 yeniden eşleme (crosswalk)

2026 sürümü sıraları değiştirdi ve bir girişi (eski System Prompt Leakage) yeniden kapsamlandırdı. Eski dokümanlarınız, Jira etiketleriniz veya tarayıcı kurallarınız hâlâ 2025 kimliklerine atıfta bulunuyorsa, prev_2025_id alanı bunları kırmadan çözmenizi sağlar.

2026 kimliğiBaşlık (TR)2025 karşılığıDeğişim
LLM01:2026Komut EnjeksiyonuLLM01:2025Sabit (#1)
LLM02:2026Hassas Bilgi İfşasıLLM02:2025Sabit (#2)
LLM03:2026Aşırı YetkiLLM06:2025↑ 6→3
LLM04:2026Tedarik ZinciriLLM03:2025↓ 3→4
LLM05:2026Veri ve Model ZehirlenmesiLLM04:2025↓ 4→5
LLM06:2026Sınırsız TüketimLLM10:2025↑ 10→6
LLM07:2026Yanlış BilgiLLM09:2025↑ 9→7
LLM08:2026Gizli Bağlam İfşasıLLM07:2025Yeniden kapsamlandı 7→8
LLM09:2026Vektör ve Gömme ZayıflıklarıLLM08:2025↓ 8→9
LLM10:2026Hatalı Çıktı İşlemeLLM05:2025↓ 5→10

Bu tabloyu elle taşımak yerine sözlüğü veri setinden üretin — belge güncellendikçe eşleme kendiliğinden doğru kalır:

# 2025 kimliginden 2026 kimligine cozumleme
remap = {x["prev_2025_id"]: x["id"] for x in items if x.get("prev_2025_id")}

def resolve(ref: str) -> str:
    # "LLM05:2025" veya sade "LLM05" gibi eski referanslari 2026'ya tasi
    key = ref if ":" in ref else f"{ref}:2025"
    return remap.get(key, ref)

print(resolve("LLM05:2025"))   # LLM10:2026 (Hatali Cikti Isleme)
print(resolve("LLM06:2025"))   # LLM03:2026 (Asiri Yetki)

Bu detaylı gerekçeleri merak ediyorsanız 2026 değişiklik genel bakışı ve derin 2025 referansı için 2025 rehberi ayrı yazılarda ele alınıyor; bu rehber çeviriyi değil, verinin tüketimini konu alır.

Bulgularınızı kanonik kimliklere eşleyin

Tarayıcınız veya pentest raporunuz kendi iç kontrol adlarını üretir. Bunları OWASP kimliklerine bağlamak için ince bir eşleme tablosu tutun — böylece raporlarınız kategori bazında toplanabilir hâle gelir:

# Tarayici/pentest kontrol adi -> OWASP LLM 2026 kimligi
FINDING_TO_OWASP = {
    "indirect_prompt_injection": "LLM01:2026",
    "cross_modal_injection":     "LLM01:2026",   # 2026: gorsel/ses de dahil
    "pii_leak":                  "LLM02:2026",
    "tool_overreach":            "LLM03:2026",
    "unsigned_model_artifact":   "LLM04:2026",
    "rag_poisoning":             "LLM05:2026",
    "no_rate_limit":             "LLM06:2026",
    "hallucinated_fact":         "LLM07:2026",
    "system_prompt_leak":        "LLM08:2026",
    "embedding_inversion":       "LLM09:2026",
    "xss_from_output":           "LLM10:2026",
}

def tag_finding(f: dict) -> dict:
    oid = FINDING_TO_OWASP.get(f["check_id"])
    f["owasp_llm_2026"] = oid
    f["owasp_title"] = by_id[oid]["tr_title"] if oid else None
    return f

Eşleme tablosunu tek bir dosyada tutmanın değeri, denetimde ortaya çıkar: bir bulgunun neden LLM03:2026 sayıldığını tek satırda gösterebilirsiniz. Eski raporlarda 2025 kimlikleri görürseniz, önce resolve()'dan geçirip sonra etiketleyin.

CI kapısı ve kapsam karnesi

İki farklı soruyu karıştırmayın. Kapsam karnesi, test paketinizin 10 kategorinin her birine en az bir kontrolle dokunup dokunmadığını ölçer — bu bir olgunluk göstergesidir, geçti/kaldı değil. Bulgu kapısı ise eşik üstü açık bir bulgu varsa build'i düşürür.

Önce kapsam karnesi:

import sys, json

items    = json.load(open("data/llm-top10-2026.json", encoding="utf-8"))
findings = json.load(open("out/findings.json", encoding="utf-8"))
by_id    = {x["id"]: x for x in items}

REQUIRED = set(by_id)                                       # 10 kanonik kimlik
covered  = {f.get("owasp_llm_2026") for f in findings} - {None}
missing  = sorted(REQUIRED - covered)

coverage = 100 * (len(REQUIRED) - len(missing)) // len(REQUIRED)
print(f"Kapsam: %{coverage}   Eksik: {', '.join(missing) or 'yok'}")

if coverage < 80:
    sys.exit(1)   # CI kapisi: esik altinda build dusur

Bu döngüyü bir GitHub Actions adımına bağlamak birkaç satır:

# .github/workflows/llm-coverage.yml
- name: OWASP LLM kapsam karnesi
  run: |
    python scripts/owasp_coverage.py \
      --dataset data/llm-top10-2026.json \
      --findings out/findings.json \
      --min-coverage 80

Bir dashboard için aynı çıktıyı kategori bazında toplayın: her id için bulgu sayısı, en yüksek şiddet ve son tarama tarihi. Veri seti başlıkları ve özetleri sağladığından, panelde tr_title'ı etiket, tr_summary'yi tooltip olarak kullanabilirsiniz — kod ile içerik ayrı kalır, liste güncellenince panel de güncellenir.

Sınır: liste ne zaman yetmez

Bu liste, model uygulamanızda bir bileşen olduğunda geçerlidir. Model bir aktöre döndüğü an — çağırabileceği araçlar, oturumlar arası taşıdığı hafıza ve aşağı akışta belirlediği sonuçlarla — risk OWASP Agentic (ASI) Top 10'a kayar. İkisini birlikte kullanın; hiçbiri o zemini tek başına kapatmaz. Ajan mimarileri için Agentic/ASI Top 10 Türkçe yazısını bu veri setiyle eşleyin; ASI için de benzer bir açık veri paketi mevcuttur.

Özetle: listeyi bir PDF gibi değil, bir bağımlılık gibi ele alın. Kimlikleri kanon, çeviriyi arayüz, prev_2025_id'yi geriye uyumluluk katmanı olarak kullanın; kapsamı ölçün, bulguyu geçitleyin. Kaynak dosyalar aşağıdaki GitHub ve Hugging Face bağlantılarında; katkı ve düzeltmeler CC BY-SA 4.0 kapsamında açıktır.

Sık Sorulan Sorular

Bu veri seti resmî OWASP yayını mı?

İngilizce kimlik (id) ve başlıklar (en_title) resmî OWASP GenAI 2026 belgesinden gelir ve normatif kabul edilmelidir. Türkçe alanlar ve JSON paketleme gayriresmî topluluk katkısıdır. Lisans CC BY-SA 4.0'dır.

Eski LLM05:2025 gibi referanslarım bozulur mu?

Hayır. Veri setindeki prev_2025_id alanından bir yeniden-eşleme sözlüğü kurup eski kimlikleri 2026 karşılığına çözebilirsiniz; örneğin LLM05:2025 kaydı LLM10:2026'ya (Hatalı Çıktı İşleme) taşınır.

Kapsam karnesi ile bulgu kapısı arasındaki fark nedir?

Kapsam karnesi test paketinizin 10 kategorinin her birine en az bir kontrolle dokunup dokunmadığını ölçer (olgunluk göstergesi). Bulgu kapısı ise eşik üstü açık bir bulgu tespit edilince CI build'ini düşürür.

Ajan/agent sistemleri de bu listeyle mi kapsanıyor?

Model uygulamada bir bileşenken bu liste geçerlidir. Model araç çağıran, hafıza taşıyan bir aktöre döndüğünde risk OWASP Agentic (ASI) Top 10'a kayar. İki listeyi birlikte kullanın.

CC BY-SA 4.0 dashboard'uma ne yükler?

ShareAlike koşulu gereği, veri setinden türettiğiniz karne ve dashboard'ları da atıf vererek ve aynı CC BY-SA 4.0 lisansıyla paylaşmanız gerekir.

Veriyi nereden ve hangi dosyadan çekerim?

GitHub deposundaki data/llm-top10-2026.json dosyasından ham JSON olarak ya da Hugging Face veri seti üzerinden datasets kütüphanesiyle yükleyebilirsiniz.

Kaynaklar

KaynakLink
OWASP GenAI — LLM Top 10 for 2026 (resmî belge)genai.owasp.org
owasp-llm-top10-2026-tr — açık veri seti (GitHub)github.com
owasp-llm-top10-2026-tr — veri seti (Hugging Face)huggingface.co