---
title: 'Sızma Testinin Yeri'
source: 'https://academia.sh/tr/kurslar/islevsel-olmayan-test/sizma-testinin-yeri'
course: 'İşlevsel Olmayan Test'
language: tr
updated: '2026-08-17T18:10:53+00:00'
license: 'CC BY-SA 4.0'
---

# Sızma Testinin Yeri

Otomasyonun bittiği noktanın ölçülmesi: bir tehdit modelinde otomatik karar verilebilen girdilerin payı, tek adımlı ve çok adımlı senaryolar arasındaki kapsama farkı ve her adımı tek tek yetkili olan bir işlem zincirinin ancak insan eliyle yazılmış bir değişmezle ihlal sayılabilmesi.

Üç yöntem de bir kural kümesine bakıyordu: statik tarama desenlere, dinamik test yanıt
imzalarına, bağımlılık taraması kayıtlara. Üçünün ortak varsayımı, aranan şeyin **önceden
adlandırılmış** olmasıdır. Ödünç sisteminin en pahalı kusuru ise hiçbir listede yoktur,
çünkü kusur kodun bir satırında değil kuralların birleşimindedir.

**Sızma testi** bu boşluğun adıdır: bir insanın sistemin kurallarını okuyup, tek tek
meşru olan işlemleri sistemin sahibinin hiç düşünmediği bir sırayla birleştirmesi. Bu ders
tekniği değil **yeri** ele alır — otomasyonun kapsayabildiği kusur sınıflarını muhakeme
gerektirenlerden ayırır ve aradaki payı sayar.

## Tehdit Modeliyle Kapsamı Saymak

Kapsam sorusunun sorulabilmesi için bir liste gerekir. **Tehdit modeli** varlıkları, giriş
noktalarını ve bunlara yönelen tehditleri sayar; buradaki liste ödünç sistemi için çıkarıldı
ve her girdi iki alan taşıyor: kararı hangi kaynağın verebildiği ve senaryonun kaç adım
olduğu.

**IO11 (varsayım):** tehdit modeli eksiksizdir. Listede olmayan bir tehdit yoktur sayılır;
gerçekte bu varsayım tutmaz ve bütün kapsama oranları bu listeye görelidir.

```js
// tehdit.mjs — odunc sisteminin tehdit modeli ve kapsamanin yontemlere dagilimi
// [tehdit, karar kaynagi, senaryo adim sayisi]
// karar kaynagi: desen (statik), yanit (dinamik), kayit (bagimlilik), muhakeme (insan)
const TEHDIT = [
  ["katalog sorgusunun birlestirilerek kurulmasi", "desen", 1],
  ["koda gomulu imza anahtari", "desen", 1],
  ["dizgiden kod ureten bicimleyici", "desen", 1],
  ["uye kaydinin kimliksiz donmesi", "yanit", 1],
  ["hata yanitinda ic yol bildirimi", "yanit", 1],
  ["odunc isteginin kimliksiz kabulu", "yanit", 1],
  ["girdinin yanitta aynen yankilanmasi", "yanit", 1],
  ["kabul edilen istegin kayda donusmesi", "yanit", 2],
  ["kuyruk istemcisinin bildirilmis kusuru", "kayit", 1],
  ["desen derleyicisinin bildirilmis kusuru", "kayit", 1],
  ["raporun toplamindan tek uyenin cikarilabilmesi", "muhakeme", 1],
  ["cezanin ortaklik uzerinden devredilmesi", "muhakeme", 4],
  ["uyeligi bitmis okuyucunun odunc sirasini korumasi", "muhakeme", 3],
  ["uzatmanin ceza esigini sifirlamasi", "muhakeme", 2],
];

const OTOMATIK = ["desen", "yanit", "kayit"];
const say = (f) => TEHDIT.filter(f).length;
const oto = (t) => OTOMATIK.includes(t[1]);

console.log(`${TEHDIT.length} tehdit girdisi`);
for (const k of [...OTOMATIK, "muhakeme"]) {
  const n = say((t) => t[1] === k);
  console.log(`  ${k.padEnd(10)}${String(n).padStart(3)}  %${((100 * n) / TEHDIT.length).toFixed(0)}`);
}
console.log(`otomatik kapsanan: ${say(oto)}/${TEHDIT.length} = %${((100 * say(oto)) / TEHDIT.length).toFixed(0)}`);

for (const [ad, f] of [["tek adimli", (t) => t[2] === 1], ["cok adimli", (t) => t[2] > 1]]) {
  const grup = TEHDIT.filter(f);
  const k = grup.filter(oto).length;
  console.log(`${ad}: ${grup.length} tehdit, ${k} otomatik = %${((100 * k) / grup.length).toFixed(0)}`);
}

const el = TEHDIT.filter((t) => !oto(t));
console.log(`\ninsan muhakemesi gerektiren ${el.length} girdi, toplam ${el.reduce((s, t) => s + t[2], 0)} adim:`);
for (const [ad, , n] of el) console.log(`  ${String(n)} adim  ${ad}`);
```

```
14 tehdit girdisi
  desen       3  %21
  yanit       5  %36
  kayit       2  %14
  muhakeme    4  %29
otomatik kapsanan: 10/14 = %71
tek adimli: 10 tehdit, 9 otomatik = %90
cok adimli: 4 tehdit, 1 otomatik = %25

insan muhakemesi gerektiren 4 girdi, toplam 10 adim:
  1 adim  raporun toplamindan tek uyenin cikarilabilmesi
  4 adim  cezanin ortaklik uzerinden devredilmesi
  3 adim  uyeligi bitmis okuyucunun odunc sirasini korumasi
  2 adim  uzatmanin ceza esigini sifirlamasi
```

İki oran arasındaki fark bu dersin ana bulgusudur. Tek adımlı tehditlerin %90'ı otomatik
karara bağlanıyor; çok adımlı tehditlerin yalnız %25'i. Otomasyon **istek başına** karar
verir: bir satır, bir yanıt, bir sürüm numarası. Adımlar arasındaki ilişki hiçbir kuralın
girdisi değildir.

Ayrım adım sayısıyla da bitmiyor. Listedeki tek adımlı muhakeme girdisi, rapor ucunun tek
bir isteğidir; yanıt kusursuz biçimlidir, yetki denetimi geçer, hiçbir iç ayrıntı sızmaz.
Kusur, dönen toplamın belirli bir sorgu ile tek bir üyeye indirgenebilmesidir — bu kararı
verebilmek için verinin **ne anlama geldiğini** bilmek gerekir.

## Tek Tek Yetkili Adımlar

Muhakeme girdilerinin en pahalısı dört adımlıydı. Ödünç sisteminde beş işlem var ve her
birinin kendi yetki koşulu bulunuyor: ortaklık ekleme yalnız üyelere açık, ceza devri
yalnız ortaklık varken, ortaklıktan çıkma yalnız ortağa. Otomatik denetim her adımda bu
koşulu sınar ve hiçbir adım kural dışı değildir.

```js
// zincir.mjs — tek tek yetkili adimlarin birlesiminden dogan ihlal ve zincir uzunlugu esigi
const BASLANGIC = { uye: true, ortak: false, oduncte: true, ceza: 0, ortakCeza: 0 };

// Her islemin kendi yetki kosulu var; hicbiri tek basina kural disi degil.
const ISLEM = {
  "ortak-ekle": { yetki: (d) => d.uye && !d.ortak, etki: (d) => ({ ...d, ortak: true }) },
  "ortak-cikar": { yetki: (d) => d.ortak, etki: (d) => ({ ...d, ortak: false }) },
  "ceza-devret": { yetki: (d) => d.ortak && d.ceza > 0, etki: (d) => ({ ...d, ceza: 0, ortakCeza: d.ortakCeza + d.ceza }) },
  "iade-et": { yetki: (d) => d.oduncte, etki: (d) => ({ ...d, oduncte: false }) },
  "kayip-bildir": { yetki: (d) => d.oduncte, etki: (d) => ({ ...d, oduncte: false, ceza: d.ceza + 30 }) },
};

// Insan eliyle yazilmis iki degismez. Dogru olan ortakligin kapanmasini sarta baglar.
const DEGISMEZ = {
  dogru: (d) => !(d.ortakCeza > 0 && !d.ortak),
  dar: (d) => !(d.ortakCeza > 0),
};

// Uzunlugu k'ya kadar olan butun yetkili islem dizilerini uretir.
function diziler(k) {
  const cikti = [];
  const yuru = (d, iz) => {
    if (iz.length) cikti.push({ iz, son: d });
    if (iz.length === k) return;
    for (const [ad, i] of Object.entries(ISLEM)) if (i.yetki(d)) yuru(i.etki(d), [...iz, ad]);
  };
  yuru(BASLANGIC, []);
  return cikti;
}

console.log(`${Object.keys(ISLEM).length} islem, her adimda yetki kosulu denetleniyor`);
console.log(`${"k".padStart(2)}${"dizi".padStart(8)}${"adim".padStart(8)}${"yetki gecen".padStart(13)}${"dogru ihlal".padStart(13)}${"dar ihlal".padStart(11)}${"dar yanlis alarm".padStart(18)}`);
for (const k of [1, 2, 3, 4, 5]) {
  const d = diziler(k);
  const adim = d.reduce((t, x) => t + x.iz.length, 0);
  const dogru = d.filter((x) => !DEGISMEZ.dogru(x.son));
  const dar = d.filter((x) => !DEGISMEZ.dar(x.son));
  console.log(`${String(k).padStart(2)}${String(d.length).padStart(8)}${String(adim).padStart(8)}` +
    `${String(adim).padStart(13)}${String(dogru.length).padStart(13)}${String(dar.length).padStart(11)}` +
    `${String(dar.length - dogru.length).padStart(18)}`);
}

const ilk = diziler(5).filter((x) => !DEGISMEZ.dogru(x.son)).sort((a, b) => a.iz.length - b.iz.length)[0];
console.log(`\nen kisa ihlal (${ilk.iz.length} adim): ${ilk.iz.join(" -> ")}`);
console.log(`son durum: ceza ${ilk.son.ceza}, ortak uzerindeki ceza ${ilk.son.ortakCeza}, ortaklik ${ilk.son.ortak}`);
```

```
5 islem, her adimda yetki kosulu denetleniyor
 k    dizi    adim  yetki gecen  dogru ihlal  dar ihlal  dar yanlis alarm
 1       3       3            3            0          0                 0
 2       8      13           13            0          0                 0
 3      17      40           40            0          2                 2
 4      28      84           84            2          4                 2
 5      45     169          169            2         10                 8

en kisa ihlal (4 adim): ortak-ekle -> kayip-bildir -> ceza-devret -> ortak-cikar
son durum: ceza 0, ortak uzerindeki ceza 30, ortaklik false
```

Dördüncü sütun her satırda üçüncüyle aynı: **atılan her adımın yetki koşulu geçti.** Yüz
altmış dokuz adımın hiçbiri kural dışı değil. Beşinci sütun dört adımda ikiye çıkıyor:
ortaklık kurulur, kitap kayıp bildirilir, ceza ortağa devredilir, ortaklık kapatılır. Sonuç,
üstünde ceza duran ama artık ortak olmayan bir üyedir.

Bu ihlali bulan şey bir kural değil, **elle yazılmış bir değişmezdir**. Ödünç sisteminin
hiçbir yerinde "ortaklık kapandığında devredilmiş ceza da geri döner" cümlesi yazılı
değildi; onu yazmak, alanı bilen bir insanın işidir. Otomasyonun bittiği nokta tam olarak
burasıdır: makine zincirleri üretebilir, ihlalin ne olduğunu söyleyemez.

Altıncı ve yedinci sütun muhakemenin kendi hata payını gösteriyor. Dar değişmez "ceza hiç
devredilemez" diyor ve meşru devirleri de ihlal sayıyor: k=4'te dört bulgunun ikisi yanlış
alarm, k=5'te on bulgunun sekizi. Yanlış yazılmış bir değişmez, yanlış yazılmış bir tarama
kuralından farksızdır — yalnız daha pahalıdır, çünkü bulgularını bir insan eler.

## Zincir Uzunluğu Eşiği

**IO12 (varsayım):** incelenecek en uzun zincir dört adımdır. Eşiğin kaynağı bir gereksinim
değil, bir bütçedir; tablonun ikinci ve üçüncü sütunu bu bütçenin neye karşılık geldiğini
verir.

**Yanlış geçme**, eşiğin altında kalan ihlaldir: k=3'te iki gerçek ihlalin ikisi de kaçtı,
k=4'te ikisi de yakalandı. **Yanlış kalma**, dar değişmezin meşru zincirleri kırmızıya
döndürmesidir ve zincir uzadıkça hızla büyür. İki sütun aynı yönde büyüdüğü için eşiği
yükseltmenin bedeli iki katlıdır: hem daha çok dizi incelenir hem de daha çok yanlış alarm
elenir.

Bedelin koşumdan bağımsız ölçüsü adım sayısıdır: k=3'te 40, k=4'te 84, k=5'te 169. Beş
işlemlik bir alanda bile sayı iki katına yakın artıyor; gerçek bir sistemde işlem sayısı
onlarcadır ve zincir uzunluğunu bir artırmak incelenecek diziyi kat kat büyütür. Sızma
testinin bir bütçeyle sınırlanmasının nedeni budur — kapsam, bulunabilecek her şey değil,
**seçilmiş bir uzunluğa kadar** her şeydir.

**Kararın sahibi:** bu bulgular yayımı durdurmaz, çünkü koşum döngüsünün içinde değildir.
Bir sızma testi bulgusu bir kayıt açar, kaydın önceliği tehdit modelindeki varlığın
değerinden gelir ve düzeltme genellikle bir kural değişikliğidir; ardından o kural
otomatikleştirilebilir hâle gelir. Muhakeme girdileri zamanla otomatik girdilere dönüşür,
ama liste hiç boşalmaz.

## Özet

- Tehdit modeli, kapsamanın sayılabilmesi için gereken listedir; on dört girdinin onu
  otomatik yöntemlerle karara bağlandı, dördü insan muhakemesi gerektirdi.
- Kapsama farkı adım sayısındadır: tek adımlı tehditlerin %90'ı otomatik, çok adımlı
  tehditlerin %25'i. Otomasyon istek başına karar verir, adımlar arasındaki ilişkiye bakmaz.
- Beş işlemlik ödünç alanında yüz altmış dokuz adımın hepsi yetki koşulunu geçti; ihlal
  ancak elle yazılmış bir değişmezle ve dört adımlık bir zincirle görünür oldu.
- Yakalanan sınıf işlem birleşiminden doğan iş mantığı kusurudur; yakalanmayan sınıf,
  değişmezi yazılmamış her kuraldır — makine zincir üretir, ihlalin tanımını üretemez.
- İnsan eliyle yazılan değişmezin de yanlış alarmı vardır: dar yazılmış bir değişmez k=5'te
  on bulgunun sekizini boşa çıkardı.
- Bedel zincir uzunluğuyla büyür: k=3'te 40 adım, k=4'te 84, k=5'te 169. Eşiğin kaynağı bir
  gereksinim değil bütçedir ve kapsam bu bütçeyle tanımlanır.

## Sonraki Adım

Buraya kadarki dört ders sistemi kötüye kullanan bir istemciyi varsaydı. Aynı sorunun bir
başka yüzü, sistemi **kullanamayan** bir okuyucudur: ekranı görmeyen, fareyi kullanmayan ya
da metni büyüterek okuyan biri için ödünç ekranı çalışıyor mu? Bu sorunun ölçütleri ve
arayüz tarafındaki karşılıkları Frontend Kalitesi kursunda kuruldu; sonraki dersin sorusu
başkadır ve bu kursun sorusudur: o ölçütlerin kaçı bir programa yaptırılabilir, kaçı elle
doğrulanmak zorundadır ve otomatik denetimin kendi yanlış alarm ile kaçırma oranı nedir.
