---
title: 'Güvensiz Seri Durumdan Çıkarma'
source: 'https://academia.sh/tr/kurslar/guvenli-kodlama/guvensiz-seri-durumdan-cikarma'
course: 'Güvenli Kodlama'
language: tr
updated: '2026-08-17T18:06:42+00:00'
license: 'CC BY-SA 4.0'
---

# Güvensiz Seri Durumdan Çıkarma

Seri durumdan çıkarmanın güvenilir tür kümesi cinsinden ölçülmesi: altı iletideki tür etiketli düğümler her derinlikte sayılır, açık tür kaydı ile izin listesinin kabul ettiği tür ve kurduğu düğüm sayısı karşılaştırılır, etiketsiz bir veri biçiminin yapı kurma noktasını sıfıra indirmesi ve karşılığında getirdiği eşleme noktası ölçülür, kod tabanına üç yeni tür eklendiğinde kabul kümesinin nasıl değiştiği çıkarılır.

Önceki altı ders dışarıdan gelen şeyi hep bir **değer** olarak ele aldı: bir metin, bir sayı,
bir bayt dizisi, bir adres. Her seferinde savunma, o değerin gideceği yerin kuralını bilerek
kuruldu. Kimi akışlarda gelen şey değer değildir: alanlarının yanında **türü** de verinin
içinde yazar ve alıcı taraf o türü okuyup karşılık gelen yapıyı kurar.

Bu ders o kurma anını sayar. Ölçü birimi **güvenilir tür kümesidir**: kaç tür kabul ediliyor,
izin listesi kaçını kapatıyor ve türü verinin içinden okumayan bir veri biçimi kaç noktayı
ortadan kaldırıyor.

## Tür Etiketli Biçim

Model bir kayıt tutar: uygulamanın tanıdığı türler ve her türü kuran işlev. Gelen iletide
`$tur` alanı hangi kaydın çağrılacağını söyler. Kayıttaki türlerin bir kısmı yalnız veri
taşır; bir kısmı kurulurken bir kaynak açar ya da bir iş başlatır.

**GC15 (varsayım):** yan etki işareti bildirimdir; bu derste hiçbir tür gerçekten bir şey
çalıştırmaz. Ölçülen şey bir etkinin gerçekleşmesi değil, **kaç türün erişilebilir olduğudur**.

```js
// bicim.mjs — tur etiketi tasiyan bir seri durumdan cikarma bicimi (kurgu model)
// yanEtki: kurulurken bir kaynak acan ya da bir is baslatan tur. Burada yalniz
// isaretlenir; hicbiri gercekten bir sey calistirmaz.
export const KAYIT = {
  Abone:        { yanEtki: false, kur: (a) => ({ tur: "Abone", no: a.no }) },
  Okuma:        { yanEtki: false, kur: (a) => ({ tur: "Okuma", deger: a.deger }) },
  Fatura:       { yanEtki: false, kur: (a) => ({ tur: "Fatura", tutar: a.tutar }) },
  IsEmri:       { yanEtki: false, kur: (a) => ({ tur: "IsEmri", no: a.no }) },
  DosyaKaynagi: { yanEtki: true,  kur: (a) => ({ tur: "DosyaKaynagi", yol: a.yol }) },
  Zamanlayici:  { yanEtki: true,  kur: (a) => ({ tur: "Zamanlayici", her: a.her }) },
  DisCagri:     { yanEtki: true,  kur: (a) => ({ tur: "DisCagri", hedef: a.hedef }) },
  Gunlukcu:     { yanEtki: true,  kur: (a) => ({ tur: "Gunlukcu", kanal: a.kanal }) },
  Onbellek:     { yanEtki: true,  kur: (a) => ({ tur: "Onbellek", boyut: a.boyut }) },
};
export const IZIN = ["Abone", "Okuma", "Fatura", "IsEmri"];

// Gelen iletiler (kurgu): ucu sistemin gercekten alisverisini yaptigi bicimler.
export const MESAJ = [
  ["okuma yukleme", { $tur: "Okuma", deger: 412 }, "beklenen"],
  ["abone kaydi", { $tur: "Abone", no: "A-100432", ek: { $tur: "IsEmri", no: 12 } }, "beklenen"],
  ["fatura ozeti", { $tur: "Fatura", tutar: 512, kalem: [{ $tur: "Okuma", deger: 5 }] }, "beklenen"],
  ["gecmis alimi", { $tur: "Okuma", deger: 7, kaynak: { $tur: "DosyaKaynagi", yol: "d1" } }, "beklenmedik"],
  ["toplu is", { $tur: "IsEmri", no: 3,
    is: { $tur: "Zamanlayici", her: 60, adim: { $tur: "DisCagri", hedef: "h" } } }, "beklenmedik"],
  ["ayar tasima", { $tur: "Onbellek", boyut: 100 }, "beklenmedik"],
];

// Bir iletideki butun tur etiketlerini, hangi derinlikte olursa olsun toplar.
export const etiketler = (o) =>
  o === null || typeof o !== "object" ? []
    : (Array.isArray(o) ? [] : o.$tur ? [o.$tur] : []).concat(Object.values(o).flatMap(etiketler));
```

Etiket toplayıcı ölçünün ilk yarısıdır. Bir iletideki tür kararı üst düzeyde bir tane
değildir; ileti bir ağaçtır ve her düğüm kendi türünü söyleyebilir. Kapsama sayılırken
sayılacak birim ileti değil, **etiket taşıyan düğümdür**.

## Kabul Edilen Tür Kümesi

Üç çözme biçimi aynı ileti kümesine uygulanıyor. Açık kayıt tanıdığı her türü kurar. İzin
listesi yalnız bildirilen dört türü kurar. Etiketsiz veri biçimi `$tur` alanını hiç okumaz;
gelen şeyi düz veri olarak bırakır.

```js
// kapsama.mjs — uc coz bicimi: acik kayit, izin listesi, etiketsiz veri bicimi
import { KAYIT, IZIN, MESAJ, etiketler } from "./bicim.mjs";

const BICIM = [
  ["acik kayit", Object.keys(KAYIT)],
  ["izin listesi", IZIN],
  ["etiketsiz veri bicimi", []],
];
const tumEtiket = MESAJ.flatMap(([, g]) => etiketler(g));
console.log(`${MESAJ.length} ileti, ${tumEtiket.length} tur etiketi tasiyan dugum, ` +
  `${new Set(tumEtiket).size} ayri tur\n`);
console.log(`${"coz bicimi".padEnd(24)}${"kabul tur".padStart(10)}${"kurulan dugum".padStart(14)}` +
  `${"yan etkili kurulum".padStart(20)}${"kabul ileti".padStart(12)}`);
for (const [ad, kabul] of BICIM) {
  let kurulan = 0, yanEtkili = 0, kabulIleti = 0;
  for (const [, govde] of MESAJ) {
    const e = etiketler(govde);
    const gecti = e.every((t) => kabul.includes(t));
    if (kabul.length === 0) { kabulIleti++; continue; }        // hicbir yapi kurulmaz
    if (gecti) { kabulIleti++; kurulan += e.length; yanEtkili += e.filter((t) => KAYIT[t].yanEtki).length; }
  }
  console.log(ad.padEnd(24) + String(kabul.length).padStart(10) + String(kurulan).padStart(14) +
    String(yanEtkili).padStart(20) + String(kabulIleti).padStart(12));
}
const erisilir = (k) => k.filter((t) => KAYIT[t].yanEtki).length;
console.log(`\nkayitta ${Object.keys(KAYIT).length} tur var, ${erisilir(Object.keys(KAYIT))} tanesi yan etkili`);
console.log(`izin listesi ${IZIN.length} tur kabul ediyor, ${erisilir(IZIN)} tanesi yan etkili`);
console.log(`etiketsiz bicimde yapi kurma noktasi: 0, elle esleme noktasi: ` +
  `${MESAJ.filter(([, , b]) => b === "beklenen").length}`);
```

```
6 ileti, 11 tur etiketi tasiyan dugum, 8 ayri tur

coz bicimi               kabul tur kurulan dugum  yan etkili kurulum kabul ileti
acik kayit                       9            11                   4           6
izin listesi                     4             5                   0           3
etiketsiz veri bicimi            0             0                   0           6

kayitta 9 tur var, 5 tanesi yan etkili
izin listesi 4 tur kabul ediyor, 0 tanesi yan etkili
etiketsiz bicimde yapi kurma noktasi: 0, elle esleme noktasi: 3
```

Açık kayıt altı iletinin altısını da kabul ediyor ve on bir düğümün on birini kuruyor;
dördü yan etkili türdür. Kabul edilen tür sayısı burada bir karar değil, bir **sonuçtur**:
kayıtta ne varsa kabul edilir.

İzin listesi kabul edilen türü dörde, kurulan düğümü beşe indiriyor ve yan etkili kurulumu
sıfırlıyor. Üç ileti reddediliyor ve üçü de beklenmedik olarak etiketlenmiş iletilerdir.
Reddin nedeni iletinin üst düzey türü değil, **derinlikteki bir düğümdür**: toplu iş
iletisinin kökü izin listesindedir, iki alt düğümü değildir.

Üçüncü satır ölçünün asıl noktasıdır. Etiketsiz veri biçiminde kurulan düğüm sıfırdır ve
bu bir savunmanın başarısı değildir — **kurulacak bir şey yoktur**. Tür kararı verinin
içinden gelmiyorsa saldırıya açık bir tür seçimi de yoktur. Karşılığında son satırdaki sayı
duruyor: uygulama gelen düz veriyi kendi türlerine üç ayrı yerde elle eşlemek zorundadır.

Üç biçimin kod tabanında yerleri de ayrıdır. Açık kayıt, iç servisler arasında tasarlanmış
bir kolaylıktır ve dış sınırda kaldığında ölçülen sayıyı üretir. İzin listesi, tür kararının
verinin içinden gelmesini kabul edip kümesini daraltır. Etiketsiz veri biçimi kararı verinin
dışına çıkarır ve ölçülecek bir tür kümesi bırakmaz. Seçim bir tercih değil, hangi sınırda
durulduğuyla ilgilidir: dış sınırda birinci biçimin ölçüsü kod tabanının büyüklüğüdür.

## Denetimin Uygulandığı Derinlik

İzin listesi kapsamanın tamamını değil, uygulandığı yer kadarını verir. Bir ileti ağaçtır ve
denetim yalnız köke uygulanabilir.

```js
// derinlik.mjs — izin listesinin uygulandigi derinlik
import { KAYIT, IZIN, MESAJ, etiketler } from "./bicim.mjs";

const kok = (g) => (g && g.$tur ? [g.$tur] : []);
console.log(`${"denetimin uygulandigi yer".padEnd(28)}${"kabul ileti".padStart(12)}` +
  `${"kurulan dugum".padStart(14)}${"yan etkili kurulum".padStart(20)}`);
for (const [ad, sec] of [["yalniz kok dugum", kok], ["her dugum", etiketler]]) {
  let ileti = 0, kurulan = 0, yan = 0;
  for (const [, g] of MESAJ) {
    if (!sec(g).every((t) => IZIN.includes(t))) continue;
    ileti++;
    const e = etiketler(g);
    kurulan += e.length;
    yan += e.filter((t) => KAYIT[t].yanEtki).length;
  }
  console.log(ad.padEnd(28) + String(ileti).padStart(12) + String(kurulan).padStart(14) +
    String(yan).padStart(20));
}
const derin = MESAJ.filter(([, g]) => etiketler(g).length > 1);
console.log(`\n${MESAJ.length} iletinin ${derin.length} tanesi birden cok dugumde tur etiketi tasiyor`);
console.log(`en derin ileti: ${etiketler(MESAJ[4][1]).join(" -> ")}`);
```

```
denetimin uygulandigi yer    kabul ileti kurulan dugum  yan etkili kurulum
yalniz kok dugum                       5            10                   3
her dugum                              3             5                   0

6 iletinin 4 tanesi birden cok dugumde tur etiketi tasiyor
en derin ileti: IsEmri -> Zamanlayici -> DisCagri
```

Aynı izin listesi, yalnız kök düğüme uygulandığında beş iletiyi kabul ediyor ve on düğüm
kuruyor; bunların üçü yan etkili türdür. Her düğüme uygulandığında kabul edilen ileti üçe,
kurulan düğüm beşe, yan etkili kurulum sıfıra iniyor. **Liste aynı listedir; değişen tek
şey kaç düğümün görüldüğüdür.**

Son satır nedenini gösteriyor: altı iletinin dördü birden çok düğümde tür etiketi taşıyor ve
en derin ileti üç düzey iniyor. Kök düğüm denetimi bu iletilerin ilk düzeyini onaylayıp
kalanını görmeden geçiriyor. Önceki dersteki yeniden yönlendirme zinciriyle aynı biçimdir:
denetlenen değer ile kullanılan değer arasına bir adım girdiğinde kapsama kaybolur.

## Yeni Tür Eklendiğinde

Kapsamanın sınavı, ölçüm yapıldıktan sonra kod tabanının değişmesiyle başlar. Üç yeni tür
ekleniyor ve hiçbiri seri durumdan çıkarmayı düşünerek yazılmıyor.

**GC16 (varsayım):** kayda tür eklemek bildirim gerektirmez; bir tür tanımlandığı anda
kayda girer. Ölçülen şey bu eklemenin kabul kümesine etkisidir.

```js
// yeni-tur.mjs — kod tabanina yeni tur eklendiginde kabul kumesi nasil degisiyor
import { KAYIT, IZIN } from "./bicim.mjs";

// Uc yeni tur kod tabanina giriyor; ikisi kurulurken bir is baslatiyor.
const YENI = { RaporIsi: { yanEtki: true }, Bildirim: { yanEtki: false }, AgIstemcisi: { yanEtki: true } };
const KAYIT2 = { ...KAYIT, ...YENI };

const yanEtkili = (kayit, kume) => kume.filter((t) => kayit[t].yanEtki).length;
console.log(`${"asama".padEnd(24)}${"kayitta tur".padStart(12)}${"acik kabul".padStart(12)}` +
  `${"izinli kabul".padStart(14)}${"kapatilan tur".padStart(15)}${"erisilen yan etkili".padStart(21)}`);
for (const [ad, k] of [["mevcut kod tabani", KAYIT], ["uc yeni tur eklendi", KAYIT2]]) {
  const tum = Object.keys(k);
  console.log(ad.padEnd(24) + String(tum.length).padStart(12) + String(tum.length).padStart(12) +
    String(IZIN.length).padStart(14) + String(tum.length - IZIN.length).padStart(15) +
    `${yanEtkili(k, tum)} / ${yanEtkili(k, IZIN)}`.padStart(21));
}
console.log(`\nyeni tur icin yazilan kod: acik kayitta 0 satir (tur tanimlandigi anda kabul edilir),`);
console.log(`izin listesinde 1 satir (mesru tur icin), etiketsiz bicimde 1 esleme noktasi`);
```

```
asama                    kayitta tur  acik kabul  izinli kabul  kapatilan tur  erisilen yan etkili
mevcut kod tabani                  9           9             4              5                5 / 0
uc yeni tur eklendi               12          12             4              8                7 / 0

yeni tur icin yazilan kod: acik kayitta 0 satir (tur tanimlandigi anda kabul edilir),
izin listesinde 1 satir (mesru tur icin), etiketsiz bicimde 1 esleme noktasi
```

Açık kabul sütunu kod tabanıyla birlikte büyüyor: dokuzdan on ikiye. Erişilen yan etkili tür
beşten yediye çıkıyor ve bu artış için kimsenin bir şey yazması gerekmedi — üç tür tanımlandı,
kabul kümesi kendiliğinden genişledi. **Açık kayıtta kapsama, kod tabanının büyümesiyle
ters yönde hareket eder.**

İzin listesi sütunu her iki satırda da dört. Kapatılan tür beşten sekize çıkıyor: liste
değişmediği hâlde kapsaması arttı, çünkü kapsama listenin uzunluğunda değil, **listenin
dışında bıraktığı kümededir**. Yan etkili erişim iki satırda da sıfır.

Etiketsiz biçim bu tabloda hiç görünmüyor, çünkü orada kabul edilen tür kümesi diye bir
büyüklük yoktur. Bedeli alt satırdadır: her yeni türün eşlemesi bir yerde elle yazılır.
Üç biçim üç ayrı yerde iş yapar — biri hiçbir şey yapmaz ve her şeyi kabul eder, biri bir
liste tutar, biri türü veriden tamamen çıkarır.

Üç eşleme noktası bugünkü sayıdır ve o da büyür. Etiketsiz biçimin bedeli sabit bir kerelik
iş değil, ileti biçimi başına tekrarlanan bir iştir: dördüncü bir meşru ileti biçimi
eklendiğinde dördüncü eşleme yazılır. Fark şudur ki bu iş **unutulduğunda ileti çözülmez** —
eksiklik bir açık değil, kırık bir akıştır ve ilk çağrıda görülür. İzin listesinde ise
unutulan bir satır kapsamayı sessizce daraltmaz, genişletmez de; kapsama listeye eklenmedikçe
sabittir.

## Özet

- Ölçü birimi güvenilir tür kümesidir. Bir iletideki tür kararı tek değildir: altı ileti 11
  etiket taşıyan düğüm içeriyor ve red kararı çoğu zaman derinlikteki bir düğümden geliyor.
- Açık kayıt 9 türün 9'unu kabul etti, 11 düğümü kurdu ve 4'ü yan etkili türdü. İzin listesi
  kabul edilen türü 4'e, kurulan düğümü 5'e indirdi, yan etkili kurulumu 0'ladı ve 3 iletiyi
  reddetti.
- Etiketsiz veri biçiminde yapı kurma noktası 0'dır ve bu bir savunmanın başarısı değil,
  kararın veriden çıkarılmasıdır. Bedeli 3 elle eşleme noktasıdır.
- Kod tabanına 3 yeni tür eklendiğinde açık kabul 9'dan 12'ye, erişilen yan etkili tür 5'ten
  7'ye çıktı ve bunun için hiçbir satır yazılmadı. İzin listesinin kabulü 4'te kaldı,
  kapattığı tür 5'ten 8'e çıktı.
- Aynı izin listesi yalnız kök düğüme uygulandığında 5 ileti kabul edildi, 10 düğüm kuruldu ve
  3 yan etkili kurulum oldu; her düğüme uygulandığında bu sayılar 3, 5 ve 0. Altı iletinin
  4'ü birden çok düğümde etiket taşıyor.
- Kapsama listenin uzunluğunda değil, listenin dışında bıraktığı kümededir: liste sabit
  kaldığı hâlde kod tabanı büyüdükçe kapsaması artar.

## Sonraki Adım

Yedi ders boyunca tek bir sınır çizildi: dışarıdan gelen veri nereye giriyor, nereden
çıkıyor, hangi metne katılıyor, hangi şablona ulaşıyor, hangi baytla saklanıyor, hangi
adrese gidiyor ve hangi türü kuruyor. Her birinde kapsama sayıldı ve dışarıda kalan nokta
yazıldı. Bütün bu ölçümlerin ortak varsayımı, sorunun **verinin kendisinde** olduğuydu.

Veri doğru olduğunda da bir soru kalır. Sözleşmeye tam uyan bir abone numarası, biçimi
kusursuz bir fatura dönemi ve izin listesinden geçen bir tür — hepsi geçerliyken, isteği
yapanın kim olduğu ve o kişinin bu kayda hakkı olup olmadığı hiç sorulmadı. Sonraki konu
**Kimlik, Oturum ve Yetki Hataları** bu soruyu aynı ölçüyle ele alır: kimlik doğrulama
gerçekleştiriminin sızdırdığı bilgi, oturumun yenilenmediği nokta ve kaç ucun nesne
düzeyinde denetim yaptığı.
