---
title: 'Enjeksiyon Saldırıları'
source: 'https://academia.sh/tr/kurslar/saldiri-teknikleri/enjeksiyon-saldirilari'
course: 'Saldırı Teknikleri ve Tehdit Ortamı'
language: tr
updated: '2026-08-17T18:08:33+00:00'
license: 'CC BY-SA 4.0'
---

# Enjeksiyon Saldırıları

Enjeksiyon sınıfının altı adımlık zincir olarak ölçülmesi: altı savunma katmanının hangi adımı kırdığı, on iki çağrı yerinin yetmiş iki adım bileşiminden kırk ikisinde denetim bulunmaması, kâğıt üzerindeki üç katmanlı kuruluşun yalnız bir çağrı yerinde tam olması, yüz doksan iki girdi-yer bileşiminden altısının altı adımı tamamlaması ve bu altısının iki çağrı yerinde toplanması.

Önceki ders on risk kalemini üç sütunla andı ve en yüksek geç kırma bedelini enjeksiyon
sınıfına verdi: altı adımlık bir zincir, üç adımında denetim noktası, kırılmadığında 480
kurgu kalem. Bu ders o satırın içini açar. Altı adımın her biri **önkoşuluyla** yazılır,
altı savunma katmanı adımlara eşlenir ve aynı girdi kümesi kurgu ölçüm ağının on iki çağrı
yerinden geçirilir.

Ölçümün tamamı biçimsel özellikler üzerinde yürür. Hiçbir girdi değeri yazılmaz, hiçbir
sorgu metni kurulmaz ve hiçbir düzeltme örneği verilmez. Girdiler yalnız dört ikili
özellikle tanımlanır: alan sözleşmesine uyuyor mu, o bağlamın **ayırıcı karakter sınıfını**
taşıyor mu, bağlam bir geri dönüş üretiyor mu, uzunluğu büyük mü. Ölçülen şey girdinin
kendisi değil, girdinin **hangi adımda durduğudur**.

## Zincirin Altı Adımı

Enjeksiyon tek bir an değildir; altı adımın hepsinin sırayla tutmasını gerektirir.

1. **Giriş.** Değer bir uçtan sisteme girer. Önkoşul: uç dışarıdan erişilebilir ve alan bu
   değeri kabul ediyor.
2. **Birleştirme.** Değer, bir yorumlayıcıya verilecek metnin **içine** yazılır. Önkoşul:
   çağrı yeri değeri ayrı bir işlenen olarak geçirmiyor.
3. **Ayrıştırma.** Yorumlayıcı, değerin bir bölümünü veri değil **sözdizimi** olarak okur.
   Önkoşul: değer o bağlamın ayırıcı karakter sınıfını taşıyor ve o sınıf kaçırılmamış.
4. **Yetki.** Değişmiş ifade, çağıran kimliğin yetkisiyle çalışır. Önkoşul: o kimlik
   hedeflenen kalemlere erişebiliyor.
5. **Geri dönüş.** Sonuç çağırana ulaşır. Önkoşul: yanıt gövdesi ya da hata metni ayrıntı
   taşıyor ve bağlam bir geri dönüş üretiyor.
6. **Çıkış.** Elde edilen kalemler dışarıya taşınır. Önkoşul: çıkış hacmi ve hedefi üzerinde
   bir sınır yok.

Adımların hiçbirinin **nasıl** yapıldığı yazılmadı; her biri neye ihtiyaç duyduğuyla
yazıldı. Savunmanın işi de tam olarak budur: bir adımın önkoşulunu ortadan kaldırmak.

**TS6:** adım dizisi ve `bedel` alanı bir modeldir; `bedel`, zincir o adımı kırılmadan
geçerse etkilenen kurgu kalem sayısıdır. **TS7:** her katman tek bir adımı kırar; koşullu
katman yalnız belirli girdi sınıfında kırar. **TS8:** adım 3 ancak girdi ayırıcı sınıfı
taşıyorsa, adım 5 ancak bağlam bir geri dönüş üretiyorsa tutar. **TS9:** aynı girdi her çağrı
yerinden ayrı geçirilir; bir yerde kırılan zincir başka bir yerde kırılmış sayılmaz.

```js
// enj/zincir.mjs — enjeksiyon sinifinin adim dizisi ve savunma katmanlari (model).
// Gercek bir sistem, gercek bir uc ve gercek bir girdi degeri yok; girdiler yalnizca
// bicimsel ozellikleriyle tanimlanir.
export const ADIM = [
  { n: 1, ad: "giris",       bedel: 0 },
  { n: 2, ad: "birlestirme", bedel: 0 },
  { n: 3, ad: "ayristirma",  bedel: 40 },
  { n: 4, ad: "yetki",       bedel: 120 },
  { n: 5, ad: "geri-donus",  bedel: 300 },
  { n: 6, ad: "cikis",       bedel: 480 },
];

export const KATMAN = [
  { ad: "alan-sozlesmesi",  kirar: 1, kosul: (g) => !g.sozlesme, mesru: 3 },
  { ad: "ayri-islenen",     kirar: 2, kosul: () => true,         mesru: 0 },
  { ad: "baglam-kacirma",   kirar: 3, kosul: () => true,         mesru: 1 },
  { ad: "en-az-yetki",      kirar: 4, kosul: () => true,         mesru: 6 },
  { ad: "sade-yanit",       kirar: 5, kosul: () => true,         mesru: 4 },
  { ad: "cikis-siniri",     kirar: 6, kosul: () => true,         mesru: 9 },
];

export const ONKOSUL = { 3: (g) => g.ayirici, 5: (g) => g.okuma };

// 16 kurgu girdi: dort ikili ozelligin butun bilesimleri. Hicbirinin degeri yazilmaz.
export const GIRDI = [];
for (const sozlesme of [true, false])
  for (const ayirici of [true, false])
    for (const okuma of [true, false])
      for (const uzun of [true, false])
        GIRDI.push({ no: GIRDI.length + 1, sozlesme, ayirici, okuma, uzun });

export const sinif = (g) => !g.sozlesme ? "sozlesme-disi"
  : g.ayirici ? "ayirici-tasiyan" : g.uzun ? "uzun-ama-uyumlu" : "duz-uyumlu";

// Kurgu olcum aginin 12 cagri yeri ve her birinde gercekten dagitilmis katmanlar.
export const CAGRI = [
  ["abone-portali.arama",     ["alan-sozlesmesi", "ayri-islenen", "baglam-kacirma", "sade-yanit"]],
  ["abone-portali.fatura",    ["alan-sozlesmesi", "ayri-islenen", "sade-yanit"]],
  ["abone-portali.itiraz",    ["alan-sozlesmesi", "ayri-islenen", "baglam-kacirma"]],
  ["toplayici.okuma-yaz",     ["ayri-islenen", "en-az-yetki"]],
  ["toplayici.toplu-aktarim", ["ayri-islenen", "en-az-yetki", "cikis-siniri"]],
  ["dogrulayici.esik",        ["alan-sozlesmesi", "ayri-islenen"]],
  ["dogrulayici.arsiv-ara",   ["alan-sozlesmesi"]],
  ["fatura-uretimi.donem",    ["ayri-islenen", "sade-yanit", "cikis-siniri"]],
  ["fatura-uretimi.rapor",    ["baglam-kacirma", "sade-yanit"]],
  ["is-emri.olustur",         ["alan-sozlesmesi", "ayri-islenen", "en-az-yetki"]],
  ["is-emri.saha-notu",       []],
  ["sube-ucu.sorgu",          ["alan-sozlesmesi", "ayri-islenen", "baglam-kacirma", "en-az-yetki"]],
];

export const yaz = (g, ...s) => console.log(s.map((v, i) =>
  (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join(""));
```

```js
// enj/olcum.mjs — ayni 16 girdi butun cagri yerlerinden gecirilir: her adimda zincir
// bir denetimle mi kirildi, yoksa onkosul mu tutmadi. Rastgelelik yok.
import { ADIM, KATMAN, ONKOSUL, GIRDI, sinif, CAGRI, yaz } from "./zincir.mjs";

const bedel = (n) => ADIM[n - 2]?.bedel ?? 0;   // n. adimda kirilirsa birikmis kalem

function yurut(girdi, dagitilan) {
  for (const a of ADIM) {
    const k = KATMAN.find((x) => x.kirar === a.n && dagitilan.includes(x.ad) && x.kosul(girdi));
    if (k) return { durak: a.n, neden: "denetim", bedel: bedel(a.n) };
    if (ONKOSUL[a.n] && !ONKOSUL[a.n](girdi))
      return { durak: a.n, neden: "onkosul", bedel: bedel(a.n) };
  }
  return { durak: 7, neden: "tamamlandi", bedel: ADIM[5].bedel };
}

console.log(`${ADIM.length} adimlik zincir, ${KATMAN.length} katman, ` +
  `${CAGRI.length} cagri yeri, ${GIRDI.length} kurgu girdi\n`);

const A = [-17, 9, 22, 13, 12];
console.log("1. katman-adim eslemesi");
yaz(A, "katman", "kirdigi", "kosul", "mesru bedel", "cagri yeri");
for (const k of KATMAN)
  yaz(A, k.ad, `${k.kirar}. adim`,
    k.kosul({ sozlesme: true }) ? "kosulsuz" : "girdi sinifina bagli",
    k.mesru, CAGRI.filter(([, d]) => d.includes(k.ad)).length);

const B = [-26, 8, 14, 13, 13];
console.log("\n2. cagri yeri basina zincir");
yaz(B, "cagri yeri", "katman", "ilk kirilan", "denetimsiz", "tamamlayan");
let denetimsiz = 0;
for (const [ad, d] of CAGRI) {
  const kirilan = ADIM.filter((a) => KATMAN.some((x) => x.kirar === a.n && d.includes(x.ad)));
  const kosulsuz = kirilan.filter((a) => KATMAN.find((x) => x.kirar === a.n).kosul({ sozlesme: true }));
  const tamam = GIRDI.filter((g) => yurut(g, d).durak === 7).length;
  denetimsiz += ADIM.length - kirilan.length;
  yaz(B, ad, d.length, kosulsuz.length ? `${kosulsuz[0].n}. adim` : "yok",
    ADIM.length - kirilan.length, `${tamam}/${GIRDI.length}`);
}
console.log(`${CAGRI.length * ADIM.length} adim-yer bilesiminin ${denetimsiz} tanesinde denetim yok`);
const KAGIT = ["ayri-islenen", "baglam-kacirma", "sade-yanit"];
console.log(`kagit uzerindeki kurulus (${KAGIT.join(" + ")}) tam olan yer: ` +
  `${CAGRI.filter(([, d]) => KAGIT.every((k) => d.includes(k))).length}/${CAGRI.length}`);

const C = [-17, 7, 15, 15, 13, 12];
console.log("\n3. girdi sinifi basina duraklar (16 girdi x 12 yer)");
yaz(C, "girdi sinifi", "girdi", "denetim durdu", "onkosul durdu", "tamamlandi", "bedel");
for (const s of [...new Set(GIRDI.map(sinif))]) {
  const kume = GIRDI.filter((g) => sinif(g) === s);
  const r = kume.flatMap((g) => CAGRI.map(([, d]) => yurut(g, d)));
  yaz(C, s, kume.length, r.filter((x) => x.neden === "denetim").length,
    r.filter((x) => x.neden === "onkosul").length,
    r.filter((x) => x.neden === "tamamlandi").length, r.reduce((t, x) => t + x.bedel, 0));
}
const hepsi = GIRDI.flatMap((g) => CAGRI.map(([ad, d]) => ({ ad, ...yurut(g, d) })));
const tam = hepsi.filter((x) => x.neden === "tamamlandi");
console.log(`${hepsi.length} bilesimin ${tam.length} tanesi alti adimi tamamladi, ` +
  `hepsi su iki yerde: ${[...new Set(tam.map((x) => x.ad))].join(", ")}`);

const D = [-14, 17, 16, 13];
console.log("\n4. gec kirmanin bedeli");
yaz(D, "kirilan adim", "birikmis kalem", "kiran katman", "mesru bedel");
for (const a of ADIM) {
  const k = KATMAN.find((x) => x.kirar === a.n);
  yaz(D, `${a.n}. adim`, bedel(a.n), k.ad, k.mesru);
}
console.log(`hic kirilmazsa ${ADIM[5].bedel} kalem; alti katmanin toplam mesru bedeli ` +
  `${KATMAN.reduce((t, k) => t + k.mesru, 0)} kalem/gun, ilk iki adimi kiran ikisininki ` +
  `${KATMAN.slice(0, 2).reduce((t, k) => t + k.mesru, 0)}`);
```

```
6 adimlik zincir, 6 katman, 12 cagri yeri, 16 kurgu girdi

1. katman-adim eslemesi
katman             kirdigi                 kosul  mesru bedel  cagri yeri
alan-sozlesmesi    1. adim  girdi sinifina bagli            3           7
ayri-islenen       2. adim              kosulsuz            0           9
baglam-kacirma     3. adim              kosulsuz            1           4
en-az-yetki        4. adim              kosulsuz            6           4
sade-yanit         5. adim              kosulsuz            4           4
cikis-siniri       6. adim              kosulsuz            9           2

2. cagri yeri basina zincir
cagri yeri                  katman   ilk kirilan   denetimsiz   tamamlayan
abone-portali.arama              4       2. adim            2         0/16
abone-portali.fatura             3       2. adim            3         0/16
abone-portali.itiraz             3       2. adim            3         0/16
toplayici.okuma-yaz              2       2. adim            4         0/16
toplayici.toplu-aktarim          3       2. adim            3         0/16
dogrulayici.esik                 2       2. adim            4         0/16
dogrulayici.arsiv-ara            1           yok            5         2/16
fatura-uretimi.donem             3       2. adim            3         0/16
fatura-uretimi.rapor             2       3. adim            4         0/16
is-emri.olustur                  3       2. adim            3         0/16
is-emri.saha-notu                0           yok            6         4/16
sube-ucu.sorgu                   4       2. adim            2         0/16
72 adim-yer bilesiminin 42 tanesinde denetim yok
kagit uzerindeki kurulus (ayri-islenen + baglam-kacirma + sade-yanit) tam olan yer: 1/12

3. girdi sinifi basina duraklar (16 girdi x 12 yer)
girdi sinifi       girdi  denetim durdu  onkosul durdu   tamamlandi       bedel
ayirici-tasiyan        4             40              4            4        2400
uzun-ama-uyumlu        2             20              4            0           0
duz-uyumlu             2             20              4            0           0
sozlesme-disi          8             88              6            2        1200
192 bilesimin 6 tanesi alti adimi tamamladi, hepsi su iki yerde: dogrulayici.arsiv-ara, is-emri.saha-notu

4. gec kirmanin bedeli
kirilan adim     birikmis kalem    kiran katman  mesru bedel
1. adim                       0 alan-sozlesmesi            3
2. adim                       0    ayri-islenen            0
3. adim                       0  baglam-kacirma            1
4. adim                      40     en-az-yetki            6
5. adim                     120      sade-yanit            4
6. adim                     300    cikis-siniri            9
hic kirilmazsa 480 kalem; alti katmanin toplam mesru bedeli 23 kalem/gun, ilk iki adimi kiran ikisininki 3
```

## Katmanın Koşulu

Birinci tablo altı katmanı tek bir sütunla ayırır: **koşul**. Beş katman koşulsuzdur —
dağıtıldıkları yerde her girdi için aynı adımı kırarlar. Bir tanesi koşulludur: alan
sözleşmesi yalnız sözleşmeyi ihlal eden girdide zinciri kırar. Sözleşmeye uyan ve ayırıcı
sınıfı taşıyan bir girdi için sözleşme katmanı **hiçbir adım kırmaz**.

Bu ayrım pratikte en sık yanlış okunan noktadır. Sözleşme doğrulaması bir enjeksiyon savunması
gibi anılır; ölçüldüğünde görülen şey, onun yalnız biçimsel olarak dışarıda kalan girdileri
durdurduğudur. Meşru bir abone adının içindeki ayırıcı karakter sınıfı da, o alanın
sözleşmesine uyar.

İkinci ayrım maliyet sütunundadır. İkinci adımı kıran katmanın meşru işe bedeli **sıfırdır**:
değeri ayrı bir işlenen olarak geçirmek hiçbir meşru isteği reddetmez. Altıncı adımı kıran
çıkış sınırının bedeli 9 kalem/gündür. Altı katmanın toplam bedeli 23 iken, ilk iki adımı
kıran ikisinin toplam bedeli 3'tür. **Erken kırmak yalnız daha az kalem kaybettirmez; kırmanın
kendisi de daha ucuzdur.**

## Çağrı Yeri Başına Kırılma

İkinci tablo dersin asıl ölçümüdür. Sınıf tektir, zincir tektir — ama savunma çağrı yeri
başına dağıtılır ve on iki yerde on iki farklı sonuç çıkar.

On iki yerin dokuzunda zincir **ikinci adımda** kırılıyor ve tek bir katman bunu yapıyor.
Bir yerde ilk kırılma üçüncü adıma kayıyor. **İki yerde koşulsuz hiçbir katman yok**: orada
zincir yalnız girdinin önkoşulları tutmadığında duruyor, savunma yüzünden değil. On iki çağrı
yeri ile altı adımın kurduğu 72 bileşimin **42'sinde hiçbir denetim yok**.

Denetimsiz bileşimlerin dağılımı da tek düze değildir. Dört katman on iki yerin dördünde ya
da daha azında bulunuyor; en yaygın katman dokuz yerde. Sayı, kapsamın **katman başına**
ölçülmesi gerektiğini gösterir: bir katmanın var olması onun her yerde var olduğu anlamına
gelmez ve zincir en zayıf çağrı yerinden yürür.

Son satır kâğıt ile sahanın farkını verir. Bir önceki ders enjeksiyon zincirini "üç adımında
denetim var" diye kaydetmişti; o kayıt, üç katmanın her yerde bulunduğunu varsayar. Ölçüm o
kuruluşun **12 çağrı yerinin yalnız 1'inde** tam olduğunu söylüyor. Sistem düzeyinde yazılan
her savunma iddiası, çağrı yeri başına sayılmadan doğrulanmış sayılmaz.

## Girdi Sınıfı ve Durak

Üçüncü tablo 16 girdiyi dört sınıfa ayırır ve 192 girdi-yer bileşiminin nerede durduğunu
sayar. İki sütun ayrı tutulur: zinciri **bir denetim** mi durdurdu, yoksa girdinin
**önkoşulu** mu tutmadı.

Ayırıcı sınıfı taşımayan girdiler üçüncü adımda kendiliğinden duruyor — hiçbir savunma iş
yapmadan. Bu, `duz-uyumlu` ve `uzun-ama-uyumlu` sınıflarının bedel sütununu sıfır yapan
şeydir. Bir savunmanın "hiçbir sorun görülmedi" demesi, çoğu zaman zincirin o girdi için
zaten önkoşulsuz olduğu anlamına gelir.

Ayırıcı sınıfı taşıyan dört girdi ise 48 bileşimin 40'ında bir denetimle durduruluyor,
4'ünde önkoşul tutmuyor ve 4'ünde zincir tamamlanıyor. Aynı dört girdi, dağıtımı eksik iki
yerde 2.400 kalemlik bedeli tek başına taşıyor.

Toplam 192 bileşimin yalnız **6'sı** altı adımı tamamlıyor ve altısı da aynı iki çağrı
yerinde. Bu iki yerin taşıdığı bedel 2.400 ve 1.200 kalemdir. Risk kalemin kendisine değil,
kalemin **kaç yerde denetimsiz** olduğuna bağlıdır: sınıf on iki yerde de aynıdır, sayı iki
yerde toplanır.

## Geç Kırmanın Bedeli

Dördüncü tablo bedeli adım adım verir. İlk üç adımda kırılan zincirin bedeli sıfırdır:
ayrıştırma gerçekleşmemiştir. Dördüncü adımda kırılırsa 40, beşincide 120, altıncıda 300
kurgu kalem etkilenmiştir; hiç kırılmazsa 480.

Sıfır bedelli üç adımın anlamı, o adımlarda kırmanın **karşılıksız** olduğu değildir. Orada
kırmak bir olayın hiç oluşmamasını sağlar; kayda düşen tek şey reddedilmiş bir istektir.
Dördüncü adımdan sonra kırmak ise her zaman bir olay kaydı, bir inceleme ve bir kapsam
sorusu üretir — bedel sütununun yazmadığı ikinci maliyet budur.

Bedelin sıçraması eşit değildir. Üçüncü adımdan dördüncüye geçiş 0'dan 40'a çıkar; beşinciden
altıncıya geçiş 120'den 300'e. **Zincirin sonuna doğru her adım bir öncekinden pahalıdır**,
çünkü her adım bir öncekinin elde ettiğini çoğaltır. En az yetki ile çıkış sınırı bu yüzden
"geç" savunmalardır: işe yararlar, ama devreye girdiklerinde kaybın bir bölümü olmuştur.

## Özet

- Enjeksiyon sınıfı altı adımlık bir zincirdir ve her adım bir önkoşula bağlıdır: erişilebilir
  uç, birleştiren çağrı yeri, ayırıcı sınıfı taşıyan değer, geniş yetki, ayrıntılı geri dönüş,
  sınırsız çıkış.
- Altı katmandan beşi koşulsuz kırar, biri koşulludur: alan sözleşmesi yalnız sözleşme dışı
  girdide kırar ve sözleşmeye uyup ayırıcı sınıfı taşıyan girdi için hiçbir adım kırmaz.
- İkinci adımı kıran katmanın meşru işe bedeli 0, altıncı adımı kıranınki 9 kalem/gündür;
  altı katmanın toplamı 23, ilk iki adımı kıran ikisinin toplamı 3'tür.
- On iki çağrı yerinin 9'unda zincir ikinci adımda kırılıyor, 1'inde üçüncüde, 2'sinde hiçbir
  koşulsuz katman yok. 72 adım-yer bileşiminin 42'sinde denetim bulunmuyor ve kâğıt üzerindeki
  üç katmanlı kuruluş 12 yerin yalnız 1'inde tam.
- 192 girdi-yer bileşiminin 6'sı altı adımı tamamlıyor ve altısı da aynı iki çağrı yerinde;
  bedel dördüncü adımdan itibaren 40, 120, 300 ve kırılmazsa 480 kalemdir.

## Sonraki Adım

Bu dersin zincirinde değer bir yorumlayıcının metnine yazılıyordu ve yorumlayıcı sunucunun
içindeydi. Aynı adım dizisi, yorumlayıcı **kullanıcının tarayıcısında** olduğunda başka bir
biçim alır: değer sunucudan geçer, bir sayfaya yerleşir ve ayrıştırma başka bir makinede
gerçekleşir. Sonraki ders bu kaymayı ölçer — üç ayrı biçimin adım sayıları neden farklıdır,
bir biçimde değer sunucuya hiç uğramadığında sunucu tarafındaki katmanların kırdığı adım
sayısı kaça iner ve o durumda ölçünün kırmadan tespite kayması ne anlama gelir.
