Ders 04 / 16
Ç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.
İçindekiler
Ö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.
# 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
paylasilabilirvesaklanabilirkararları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
"""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-Cookieile gider, geri dönüşte yalnız ad–değer çiftiCookiealanı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ış
paylasilabilirkararı verir.saklanabilirtemiz 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.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.