İçeriğe geç
academia.sh

Ders 09 / 15

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.

İçindekiler

Üç 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.

// 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.

// 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.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat