---
title: 'Çerezler ve Durum Taşıma'
source: 'https://academia.sh/tr/kurslar/uygulama-protokolleri/cerezler-ve-durum-tasima'
course: 'Uygulama Katmanı Protokolleri'
language: tr
updated: '2026-08-17T18:06:58+00:00'
license: 'CC BY-SA 4.0'
---

# Çerezler ve Durum Taşıma

Çerezin kapsam kuralı hangi iletilere iliştiğini belirler, im kuralı saklanan yanıtın kime gideceğini; kırk alışverişte üç kapsam kuralı sırasıyla 11, 24 ve 40 ileti taşır ve imsiz kalan iki alışveriş aracıya iki yanlış paylaşılabilirlik kararı aldırır.

Önceki ders içerik pazarlığını kurdu: aynı adres birden çok gösterime karşılık gelir ve
aracı hangi kopyayı kime vereceğini başlık alanlarından çıkarır. Pazarlık, gösterimi
isteğin **biçim tercihine** göre seçer — dil, kodlama, ortam türü. Bunların hepsi
isteğin kendisinde yazılıdır ve aracı hepsini okur.

Peki yanıt biçime değil **kişiye** özelse? O zaman seçimi yapan alan artık tercihi değil,
kimliği taşımak zorundadır. **Çerez (cookie)**, kişiye özelliğin kendisini taşıyan alandır.
Bu dersin sorusu çerezin ne işe yaradığı değil — aracının onu görünce ne bildiği, ve
görmediğinde ne bilemediğidir.

## Durumsuz Protokolde Durum

HTTP **durumsuz (stateless)** tanımlanır: her istek kendi başına anlaşılır olmalı, sunucu
önceki isteği hatırlamak zorunda kalmamalıdır. Çerez bu tanımı bozmaz, etrafından dolaşır.
Sunucu durumu kendinde tutmaz; **istemcide tutar** ve istemci onu her istekte geri gönderir.
Böylece her istek yine kendi başına anlaşılır kalır, çünkü durum artık iletinin içindedir.

Alışveriş iki alandan ibarettir. Sunucu yanıtta `Set-Cookie` alanıyla bir ad–değer çifti ve
ona bağlı nitelikleri bildirir; istemci sonraki isteklerde `Cookie` alanıyla ad–değer
çiftini geri gönderir. Nitelikler yanıtta gider, geri dönüşte gitmez: istemci yalnız çifti
yollar.

```text
# ogretilen dokum , calistirilmamistir

sunucu -> istemci
  HTTP/1.1 200 OK
  Set-Cookie: oturum=k7; Path=/oturum; Domain=istasyon.ornek; Max-Age=3600;
              HttpOnly; SameSite=Strict; Secure
  Cache-Control: private
  Vary: Cookie

istemci -> sunucu
  GET /oturum/ozet HTTP/1.1
  Host: istasyon.ornek
  Cookie: oturum=k7
```

Niteliklerin her biri bir soruya yanıt verir. `Domain` ve `Path` çerezin **kapsamını**
belirler: hangi konak ve hangi yol öneki için gönderileceğini. `Max-Age` ömrünü belirler;
verilmezse çerez oturumluktur ve istemci kapandığında düşer. `HttpOnly`, çerezi belge
içindeki betiklerin okumasına kapatır. `SameSite`, çerezin başka bir kaynaktan tetiklenen
isteklerde taşınıp taşınmayacağını belirler. `Secure`, çerezi taşımanın türüne bağlar.

Yanıt tarafındaki iki alan aracıyı doğrudan ilgilendirir. `Cache-Control: private`, yanıtın
paylaşılan bir önbelleğe konmaması gerektiğini bildirir. `Vary: Cookie`, saklanan kopyanın
hangi istek alanına bağlı olduğunu bildirir — aynı adresin `Cookie` alanına göre ayrı
kopyaları vardır. Ortak tanımın **kişiye özel imi** bu iki alanın taşıdığı bildirimdir.

Kimlik doğrulama akışının kendisi bu kursun konusu değildir; oturum açma, oturum yenileme
ve belirteç kullanımı **Kimlik Doğrulama ve Yetkilendirme** kursunda kuruldu. Burada çerez
bir kimlik düzeneği olarak değil, bir **kapsam kuralı** olarak ölçülür.

## Çerezin Değeri Aracıya Ne Söyler

Çerez bir ad–değer çiftidir ve değerin anlamını yalnız sunucu bilir. `oturum=k7` dizgisi
aracı için bir dizgidir: kimin oturumu olduğunu, ne kadar yetki taşıdığını, hatta bir oturum
belirteci mi yoksa bir dil tercihi mi olduğunu söylemez. Aracı uygulamayı bilmez; çerezin
değerini çözmeye kalksaydı uygulamayı bilmiş olurdu.

Bunun doğrudan bir sonucu var: **aracı, çerezin varlığından yanıtın kişiye özel olduğunu
çıkaramaz.** Çıkarsaydı, yalnız bir dil tercihi taşıyan çerez yüzünden paylaşılabilir bir
yanıtı saklamaktan vazgeçerdi. Tersini de yapamaz: çerezin yokluğundan yanıtın
paylaşılabilir olduğunu çıkaramaz, çünkü sunucu kimliği başka bir alandan da okumuş olabilir.

Karar bu yüzden çerezde değil, **yanıttaki imdedir**. Sunucu ne bildirirse aracı onu bilir.
Ortak kurgunun kişiye özel imi tam olarak bu bildirimdir ve iletide görünen tek kişiye
özellik göstergesidir. Çerezin kendisi ölçüme bir karar eklemez; ölçüme giren şey çerezin
**hangi iletilerde bulunduğudur**, ne taşıdığı değil.

Ömür niteliği de aynı sınıfa girer. `Max-Age` verilmiş bir çerez ile oturumluk bir çerez
arasındaki fark istemcinin çerezi ne kadar saklayacağıdır; aracının o iletiden alacağı karar
ikisinde de aynıdır. Aracı çerezin ne zaman düşeceğini bilmez ve bilmesi gerekmez.

## İki Ayrı Kural

Çerezle ilgili iki karar vardır ve karıştırılmaları en sık görülen kusurdur.

**Kapsam kuralı** isteği ilgilendirir: çerez **hangi iletilerde taşınır?** Bunu `Domain` ve
`Path` belirler ve kararı istemci verir. **İm kuralı** yanıtı ilgilendirir: saklanan yanıt
**kime gider?** Bunu `Cache-Control` ve `Vary` belirler ve kararı sunucu bildirir, aracı
uygular.

İkisi bağımsızdır. Kapsam doğru kurulmuş bir çerez, imi konmamış bir yanıtla birlikte
gidebilir; o zaman çerez doğru yere gitmiştir ama yanıt yanlış kişiye verilebilir. Tersi de
olur: im doğru konmuş bir yanıt, kapsamı gereğinden geniş bir çerezle birlikte gidebilir.

Ölçümün varsayımları:

- **HA41** — Kırk alışveriş ortak kurgudan üretilir; kâhin kurguyu biz ürettiğimiz için
  bilinir ve her alışverişte yanıtın gerçekten kişiye özel olup olmadığını söyler.
- **HA42** — Üç kapsam kuralı denenir: yalnız oturum yolu, ölçüm ve oturum yolu öneki,
  konağın tümü. Kapsam kuralı yalnız yola bakar; kural kâhini kullanmaz.
- **HA43** — Kişiye özel im, iletide görünen tek bildirimdir. Sunucu kimi kişiye özel
  yanıtta imi koymayı atlar; **iletide yazanı doğrulayan hiçbir şey yoktur.**
- **HA44** — Aracı imi gördüğünde `paylasilabilir` ve `saklanabilir` kararlarını fazladan
  gidiş–dönüş olmadan alır; görmediğinde ikisini de alamaz ve sunucuya bir tur daha atar.
- **HA45** — Bayt sayımı alan adı, değer ve ayraç uzunluğundan hesaplanır; ölçüm bir ağ
  ölçümü değil, ileti içeriğinin sayımıdır.

## Ölçüm

```python
"""Cerez kapsami ve durum tasima: aracinin ozel imden aldigi karar.

Bolum 1 - kapsam kurali cerezi hangi iletilere ilistiriyor.
Bolum 2 - im alani gorunurken ve zarfa alinmisken karar tablosu.
"""
TOHUM = 20260809
GUVENLI = {"GET", "HEAD"}
ETKISIZ = {"GET", "HEAD", "PUT", "DELETE"}
YONTEMLER = ["GET", "GET", "GET", "HEAD", "POST", "PUT", "DELETE"]
YOLLAR = ["/olcum/kuzey", "/olcum/yamac", "/ozet", "/kayit", "/oturum"]
KARARLAR = ("saklanabilir", "paylasilabilir", "taze", "yinelenebilir",
            "yonlendirilebilir")


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def alisverisler(sayi=40):
    r, liste = uretec(TOHUM), []
    for i in range(sayi):
        yontem, yol = YONTEMLER[r(7)], YOLLAR[r(5)]
        ozel = yol == "/oturum" or r(5) == 0
        degisti = r(3) == 0
        liste.append({"no": i + 1, "yontem": yontem, "yol": yol,
                      "ozel": ozel, "degisti": degisti,
                      "ozel_imi": ozel and r(4) != 0,
                      "damga_atladi": degisti and r(6) == 0})
    return liste


def kahin(a):
    return {"saklanabilir": a["yontem"] in GUVENLI and not a["ozel"],
            "paylasilabilir": not a["ozel"], "taze": not a["degisti"],
            "yinelenebilir": a["yontem"] in ETKISIZ,
            "yonlendirilebilir": True}


def ileti(a, gorunur):
    tam = {"yontem": a["yontem"], "yol": a["yol"], "konak": "istasyon.ornek",
           "ozel_imi": a["ozel_imi"],
           "dogrulayici": a["degisti"] and not a["damga_atladi"]}
    return {k: v for k, v in tam.items() if k in gorunur}


def bayt(i):
    return sum(len(k) + len(str(v)) + 4 for k, v in i.items())


def araci(i):
    k = {}
    if "yontem" in i:
        k["yinelenebilir"] = i["yontem"] in ETKISIZ
    if "ozel_imi" in i:
        k["paylasilabilir"] = not i["ozel_imi"]
        if "yontem" in i:
            k["saklanabilir"] = i["yontem"] in GUVENLI and not i["ozel_imi"]
    if "dogrulayici" in i:
        k["taze"] = not i["dogrulayici"]
    if "konak" in i:
        k["yonlendirilebilir"] = True
    return k


GORUNUR = {"açık": ("yontem", "yol", "konak", "ozel_imi", "dogrulayici"),
           "im zarfta": ("yontem", "yol", "konak", "dogrulayici")}
KAPSAM = {"oturum yolu": lambda a: a["yol"] == "/oturum",
          "ölçüm öneki": lambda a: a["yol"].startswith(("/olcum", "/oturum")),
          "konağın tümü": lambda a: True}
A = alisverisler()

print(f"alışveriş {len(A)} | karar {len(A) * len(KARARLAR)} | kişiye özel "
      f"{sum(a['ozel'] for a in A)} | imsiz kalan "
      f"{sum(a['ozel'] and not a['ozel_imi'] for a in A)}")
print("imsiz kalan alışverişler:",
      [(a["no"], a["yontem"], a["yol"]) for a in A
       if a["ozel"] and not a["ozel_imi"]])
print()
print("kapsam kuralı  çerez taşıyan  özel ve taşıyan  özel ama taşımayan"
      "  gereksiz taşıyan")
for ad, kural in KAPSAM.items():
    print(f"  {ad:12s} {sum(kural(a) for a in A):11d}"
          f" {sum(kural(a) and a['ozel'] for a in A):16d}"
          f" {sum(not kural(a) and a['ozel'] for a in A):19d}"
          f" {sum(kural(a) and not a['ozel'] for a in A):17d}")
print()
print("karar              açık: doğru yanlış   im zarfta: doğru yanlış alınamayan")
for karar in KARARLAR:
    s = {}
    for ad in GORUNUR:
        d = y = e = 0
        for a in A:
            g, v = kahin(a), araci(ileti(a, GORUNUR[ad]))
            if karar not in v:
                e += 1
            elif v[karar] == g[karar]:
                d += 1
            else:
                y += 1
        s[ad] = (d, y, e)
    print(f"  {karar:18s} {s['açık'][0]:5d} {s['açık'][1]:6d}"
          f" {s['im zarfta'][0]:16d} {s['im zarfta'][1]:6d}"
          f" {s['im zarfta'][2]:10d}")
print()
print("görünürlük   doğru  yanlış  alınamayan  fazladan tur   bayt")
for ad in GORUNUR:
    d = y = e = t = b = 0
    for a in A:
        g, v = kahin(a), araci(ileti(a, GORUNUR[ad]))
        eksik = False
        for karar in KARARLAR:
            if karar not in v:
                e += 1
                eksik = True
            elif v[karar] == g[karar]:
                d += 1
            else:
                y += 1
        t += 1 if eksik else 0
        b += bayt(ileti(a, GORUNUR[ad]))
    print(f"  {ad:10s} {d:5d} {y:7d} {e:11d} {t:13d} {b:6d}")
```

```
alışveriş 40 | karar 200 | kişiye özel 17 | imsiz kalan 2
imsiz kalan alışverişler: [(1, 'POST', '/kayit'), (34, 'POST', '/kayit')]

kapsam kuralı  çerez taşıyan  özel ve taşıyan  özel ama taşımayan  gereksiz taşıyan
  oturum yolu           11               11                   6                 0
  ölçüm öneki           24               12                   5                12
  konağın tümü          40               17                   0                23

karar              açık: doğru yanlış   im zarfta: doğru yanlış alınamayan
  saklanabilir          40      0                0      0         40
  paylasilabilir        38      2                0      0         40
  taze                  37      3               37      3          0
  yinelenebilir         40      0               40      0          0
  yonlendirilebilir     40      0               40      0          0

görünürlük   doğru  yanlış  alınamayan  fazladan tur   bayt
  açık         195       5           0             0   3524
  im zarfta    117       3          80            40   2859
```

## Kapsamın Ödettiği

Üst tablo üç kapsam kuralını yan yana koyuyor ve hiçbiri sorunsuz değil.

**Oturum yoluna daraltılmış** kural çerezi **11** iletide taşıyor ve bu on birin hepsi
gerçekten kişiye özel. Gereksiz taşıma **0**. Bedeli sağdaki sütunda: kişiye özel olan
**6** yanıt kapsamın dışında kalıyor. Kurgu bunu doğrudan söylüyor — kişiye özellik yolun
kendisinden gelmiyor, sunucu `/oturum` dışındaki kimi yanıtı da kişiye özel üretiyor.

**Konağın tümüne açılmış** kural bu altısını kapatıyor: kapsam dışında kalan kişiye özel
yanıt **0**. Karşılığında çerez **23** iletide gereksiz taşınıyor — kırk alışverişin yarıdan
fazlasında, hiçbir işe yaramadan. Aradaki **ölçüm öneki** kuralı ikisinin ortası: **12**
gereksiz taşıma ve kapsam dışında kalan **5** kişiye özel yanıt.

Örüntü şudur: **kapsam kuralı yola bakar, kişiye özellik ise yoldan çıkmaz.** Kuralı
genişletmek kapsam dışında kalanı azaltır ama gereksiz taşımayı doğrusal olarak büyütür.
İkisini birden sıfırlayan bir yol yoktur, çünkü kapsam kuralının bilebileceği tek şey
adrestir.

## İmin Ödettiği

Alt tablolar ikinci kurala bakıyor. Kırk alışverişin **17**'sinde yanıt kişiye özel, ve
sunucu bunların **2**'sinde imi koymayı atlamış. Aracı iki alışverişte de yanıtı
paylaşılabilir sanıyor: `paylasilabilir` satırında **38** doğru, **2** yanlış.

`saklanabilir` satırı **40** doğru veriyor ve bu bir tesadüf değil. İmsiz kalan iki
alışverişin ikisi de `POST /kayit`; ikisinin de yöntemi zaten güvenli değil. Eksik im,
kararı ancak **başka türlü saklanabilir olan** bir yanıtta ödetir. Ölçümde bu koşulu
sağlayan alışveriş yok, o yüzden bu satır temiz kalıyor. Aynı eksiklik güvenli yöntemli bir
alışverişte olsaydı yanlış sayısı ikiden dörde çıkardı.

İki yanlış, iki yüz kararlık bir kümede **0,0100**'lük bir paydır. Bu kümede ölçülebilen en
küçük fark **1/200 = 0,0050**'dir; iki yanlış onun iki katıdır ve ölçüm bandının içindedir.
Bundan küçük bir fark bu kümeyle savunulamaz.

Son tabloda açık rejim **195** doğru, **5** yanlış, **0** alınamayan veriyor. Beş yanlışın
**2**'si buradaki eksik imden geliyor; kalan üçü `taze` satırında duruyor ve bambaşka bir
alandan, doğrulayıcı damgasından kaynaklanıyor. O alan bu derste ölçülmüyor.

## Yanlış Kurulmuş Kapsam ve Daraltmalar

Kapsamın geniş kurulması bir saldırı değil, bir **yapılandırma kusurudur**: kural yazılmış,
sözdizimi doğru, çerez çalışıyor ve hiçbir belirti vermiyor. Sayılan üç yüzey ve her birini
kapatan alan şunlardır.

**Birinci yüzey — gereksiz taşıma.** Konağın tümüne açılmış kapsamda çerez **23** iletide
hiçbir işe yaramadan taşınıyor. Bu iletilerin her biri aracının önünden geçiyor ve aracı
çerez alanını okuyabiliyor. **Daraltma:** `Path` niteliği oturum yoluna çekilirse gereksiz
taşıma **0**'a iner; bedeli, kapsam dışında kalan **6** kişiye özel yanıttır. `Domain`
niteliğinin verilmemesi kapsamı tek konağa bağlar; verilmesi onu alt adlara açar. `SameSite`
niteliği kapsamı yola göre değil, **isteği başlatan bağlama** göre daraltır ve `Path`
daraltmasının kapatamadığı bir yönü kapatır: aynı yola giden ama başka bir kaynaktan doğan
istek.

**İkinci yüzey — imsiz saklanan yanıt.** İki alışverişte aracı yanlış `paylasilabilir`
kararı veriyor. Böyle bir yanıtın paylaşılan bir önbelleğe konması, kişiye özel bir kopyanın
başka bir isteğe verilmesi demektir. **Daraltma:** yanıta `Cache-Control: private` konması
kararı doğrulur; `Vary: Cookie` ise saklanan kopyayı `Cookie` alanına bağlar ve aynı adresin
kopyalarını birbirinden ayırır. İkisi de sunucunun bildirimidir ve konmadıklarında aracı
bunu anlayamaz.

**Üçüncü yüzey — aracının imi görmesi.** Aracı hangi iletinin kişiye özel olduğunu okuyor;
bu, kararları gidiş–dönüşsüz almasının koşulu. **Daraltma:** im alanı taşıma zarfına
alınırsa aracı onu göremez. Son tablodaki `im zarfta` satırı bedeli veriyor: **80** karar
ortadan uçlara taşınıyor, kırk alışverişin kırkında birer tur daha atılıyor ve bayt
**3524**'ten **2859**'a iniyor. Kazanç ise yanlış sayısının **5**'ten **3**'e inmesidir —
aracının alamadığı karar, yanlış alamadığı karardır.

## Özet

- Çerez, durumu istemcide tutarak durumsuz protokolde durum taşır; nitelikler yanıtta
  `Set-Cookie` ile gider, geri dönüşte yalnız ad–değer çifti `Cookie` alanında taşınır.
- Kapsam kuralı çerezin **hangi iletide** taşınacağını, im kuralı saklanan yanıtın **kime**
  gideceğini belirler; ikisi bağımsızdır ve ayrı ayrı yanlış kurulabilir.
- Üç kapsam kuralı sırasıyla **11**, **24** ve **40** ileti taşır; kapsam genişledikçe
  dışarıda kalan kişiye özel yanıt **6**'dan **0**'a iner, gereksiz taşıma **0**'dan
  **23**'e çıkar.
- Kırk alışverişin **17**'si kişiye özel, **2**'sinde im konmamış; aracı iki yanlış
  `paylasilabilir` kararı verir. `saklanabilir` temiz kalır çünkü o iki alışverişin yöntemi
  zaten güvenli değildir.
- İm alanı taşıma zarfına alındığında yanlış **5**'ten **3**'e iner ama **80** karar uçlara
  taşınır ve kırk tur borcu doğar; gizlemenin bedeli budur.

## Sonraki Adım

Çerez bir başlık alanıdır ve kapsamı içindeki **her** istekte yeniden gönderilir. Kırk
alışverişte konak adı kırk kez, yöntem kırk kez, çerez kapsamı ne kadarsa o kadar kez
tekrarlanır — hepsi aynı bağlantı üzerinde, hepsi baştan yazılarak. Sonraki ders bu
tekrarın nasıl paketlendiğine bakar: metin satırından ikili çerçeveye geçiş aracıya ne
kazandırır, başlık sıkıştırması hangi alanı onun için okunmaz hâle getirir ve okunmayan
alanın kararı nereye taşınır.
