Ders 16 / 22
Siteler Arası Betik Çalıştırma
Üç biçimin ayrı adım dizisi olarak ölçülmesi: yansıyan beş, saklı altı, belge nesnesi tabanlı dört adım; sunucu tarafındaki üç katmanın belge nesnesi tabanlı biçimde kırdığı adım sayısının sıfır olması, sekiz sayfada yirmi dört bileşimin üçünde hiçbir halkanın kırılamaması, yalnız son adımda kırılan yedi bileşimin günlük yüz doksan oturumluk bedeli ve tarayıcı tarafındaki tek katmanın üç biçimi birden kapatması.
İçindekiler
Önceki dersin zincirinde yorumlayıcı sunucunun içindeydi ve altı adımın üçü sunucuda geçiyordu. Bu ders aynı adım dizisini yorumlayıcı kullanıcının tarayıcısında olduğunda ölçer. Değişen tek şey ayrıştırmanın nerede yapıldığıdır; sonuç, zincirin uzunluğunun ve kırılabilen halkanın üç ayrı biçimde üç ayrı yere düşmesidir.
Üç biçim ayrılır: değerin aynı yanıtta geri döndüğü yansıyan biçim, değerin önce depoya yazılıp sonra her görüntüleyene sunulduğu saklı biçim ve değerin sunucuya hiç uğramadığı belge nesnesi tabanlı biçim. Ölçüm boyunca hiçbir betik gövdesi, hiçbir değer ve hiçbir sayfa kaynağı yazılmaz; biçimler yalnız adım dizileriyle anılır.
Üç Adım Dizisi
Yansıyan biçim, beş adım. (1) Değer bir istek alanında uca ulaşır — önkoşul: uç o alanı yanıtına geri yazıyor. (2) Değer, yanıtta kod olarak okunacak bir konuma yerleşir — önkoşul: o konumun bağlamına göre kodlama yapılmıyor. (3) Bağlantı kurbana ulaşır ve kurban onu kendi oturumuyla açar — önkoşul: bir teslim kanalı var. (4) Tarayıcı yerleşen değeri çalıştırır — önkoşul: sayfanın içerik politikası bu kaynağa izin veriyor. (5) Çalışan kod oturum kalemine erişip dışarı taşır — önkoşul: çerez betiğe açık.
Saklı biçim, altı adım. Yansıyan biçimin ilk adımı ikiye ayrılır: değer önce bir yazma ucundan depoya girer, sonra bir görüntüleme yolunda yanıta yerleşir. Karşılığında üçüncü adımın önkoşulu ortadan kalkar: kimseyi bir bağlantıya yönlendirmek gerekmez, sayfayı kendi işi için açan herkes zinciri kendisi tamamlar. Zincir bir adım uzar ve teslim halkası bedavaya gelir.
Belge nesnesi tabanlı biçim, dört adım. (1) Değer istemci tarafında bir kaynaktan okunur — önkoşul: adres parçası ya da yerel depolama gibi sunucuya gitmeyen bir kaynak kullanılıyor. (2) İstemci betiği değeri, kod olarak yorumlanan bir hedefe yazar — önkoşul: hedef seçimi sabit değil. (3) Tarayıcı çalıştırır. (4) Erişim ve çıkış. Bu dizide sunucuda geçen adım yoktur; sunucu isteği görmez, kaydına düşmez, yanıtını değiştirmez.
Üç dizinin ortak noktası son iki adımdır: çalışma ve çıkış. Bu, savunmanın niçin iki ayrı yerde durabildiğini açıklar — biri değerin yanıta yerleşmesini, öteki tarayıcının onu çalıştırmasını engeller. Ayrıldıkları nokta ise başlangıçtır: yansıyan ve saklı biçim sunucudan geçer, üçüncüsü geçmez.
TS10: her biçim ayrı bir adım dizisidir. TS11: her katman her biçimde belirli bir adımı kırar; kırmadığı biçimde değeri yoktur. TS12: bağlantı başına teslimde bedel kurgu 12 kişidir, görüntüleme başına teslimde sayfanın günlük görüntüleme sayısıdır. TS13: ilk kırılan halka, o sayfada dağıtılmış katmanların kırdığı en küçük adım indeksidir.
// xss/bicim.mjs — siteler arasi betik calistirmanin uc bicimi, adim dizileri ve katmanlar // (model). Gercek bir sayfa, gercek bir deger ve hicbir betik govdesi yok. export const BICIM = { yansiyan: { adim: ["giris", "yerlesme", "teslim", "calisma", "cikis"], taraf: ["sunucu", "sunucu", "kurban", "tarayici", "tarayici"], teslim: "baglanti basina" }, sakli: { adim: ["yazma", "depolama", "yerlesme", "goruntuleme", "calisma", "cikis"], taraf: ["sunucu", "sunucu", "sunucu", "kurban", "tarayici", "tarayici"], teslim: "goruntuleme basina" }, belgeNesnesi: { adim: ["istemci-kaynagi", "hedefe-yazma", "calisma", "cikis"], taraf: ["tarayici", "tarayici", "tarayici", "tarayici"], teslim: "baglanti basina" }, }; // kirar[bicim] = 1 tabanli adim indeksi ya da 0 (o bicimde hicbir adimi kirmaz). export const KATMAN = [ { ad: "girdi-sozlesmesi", yer: "sunucu", kirar: { yansiyan: 1, sakli: 1, belgeNesnesi: 0 }, mesru: 3 }, { ad: "depo-temizleme", yer: "sunucu", kirar: { yansiyan: 0, sakli: 2, belgeNesnesi: 0 }, mesru: 2 }, { ad: "cikti-kodlama", yer: "sunucu", kirar: { yansiyan: 2, sakli: 3, belgeNesnesi: 0 }, mesru: 0 }, { ad: "icerik-politikasi", yer: "tarayici", kirar: { yansiyan: 4, sakli: 5, belgeNesnesi: 3 }, mesru: 7 }, { ad: "istemci-hedef-secimi", yer: "istemci-kodu", kirar: { yansiyan: 0, sakli: 0, belgeNesnesi: 2 }, mesru: 1 }, { ad: "cerez-bayragi", yer: "tarayici", kirar: { yansiyan: 5, sakli: 6, belgeNesnesi: 4 }, mesru: 4 }, ]; export const BAGLANTI = 12; // Kurgu olcum aginin sekiz sayfasi: dagitilmis katmanlar ve gunluk goruntuleme sayisi. export const SAYFA = [ ["abone-portali.arama", ["girdi-sozlesmesi", "cikti-kodlama", "icerik-politikasi", "cerez-bayragi"], 210], ["abone-portali.itiraz", ["girdi-sozlesmesi", "depo-temizleme", "cikti-kodlama", "cerez-bayragi"], 90], ["abone-portali.fatura", ["cikti-kodlama", "icerik-politikasi", "cerez-bayragi"], 340], ["saha-uygulamasi.is-emri", ["girdi-sozlesmesi", "cikti-kodlama", "cerez-bayragi"], 160], ["saha-uygulamasi.saha-notu", ["cerez-bayragi"], 75], ["sube-ucu.pano", ["cikti-kodlama", "icerik-politikasi"], 40], ["sube-ucu.rapor-baglantisi", ["istemci-hedef-secimi", "cerez-bayragi"], 55], ["yonetim.olcum-arama", [], 20], ]; export const yaz = (g, ...s) => console.log(s.map((v, i) => (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join(""));
// xss/olcum.mjs — uc bicim sekiz sayfada kosturulur: ilk kirilan halka, sunucu tarafinin // kirdigi adim ve kirilmadiginda etkilenen oturum sayisi. Rastgelelik yok. import { BICIM, KATMAN, SAYFA, BAGLANTI, yaz } from "./bicim.mjs"; const adlar = Object.keys(BICIM); const AD = { yansiyan: "yansiyan", sakli: "sakli", belgeNesnesi: "belge nesnesi" }; const ilkKirilan = (b, d) => Math.min(...KATMAN .filter((k) => d.includes(k.ad) && k.kirar[b] > 0).map((k) => k.kirar[b]), Infinity); const bedel = (b, gor) => (b === "sakli" ? gor : BAGLANTI); console.log(`${adlar.length} bicim, ${KATMAN.length} katman, ${SAYFA.length} kurgu sayfa\n`); const A = [-16, 7, 10, 12, 20]; console.log("1. bicim basina zincir"); yaz(A, "bicim", "adim", "sunucuda", "kirabilen", "teslim"); for (const b of adlar) yaz(A, AD[b], BICIM[b].adim.length, BICIM[b].taraf.filter((t) => t === "sunucu").length, KATMAN.filter((k) => k.kirar[b] > 0).length, BICIM[b].teslim); const B = [-22, -14, 10, 8, 15]; console.log("\n2. katman-adim eslemesi"); yaz(B, "katman", "yer", "yansiyan", "sakli", "belge nesnesi"); for (const k of KATMAN) yaz(B, k.ad, k.yer, k.kirar.yansiyan || "-", k.kirar.sakli || "-", k.kirar.belgeNesnesi || "-"); const sunucu = KATMAN.filter((k) => k.yer === "sunucu"); console.log(`sunucu tarafindaki ${sunucu.length} katmanin belge nesnesi tabanli bicimde ` + `kirdigi adim sayisi: ${sunucu.filter((k) => k.kirar.belgeNesnesi > 0).length}`); const C = [-26, 7, 12, 12, 15]; console.log("\n3. sayfa basina ilk kirilan halka"); yaz(C, "sayfa", "katman", "yansiyan", "sakli", "belge nesnesi"); let acik = 0, oturum = 0; for (const [ad, d, gor] of SAYFA) { const h = adlar.map((b) => ilkKirilan(b, d)); h.forEach((v, i) => { if (v === Infinity) { acik++; oturum += bedel(adlar[i], gor); } }); yaz(C, ad, d.length, ...h.map((v) => (v === Infinity ? "kirilmiyor" : `${v}. adim`))); } console.log(`${SAYFA.length * adlar.length} sayfa-bicim bilesiminin ${acik} tanesinde hicbir ` + `halka kirilmiyor; bu bilesimlerin gunluk bedeli ${oturum} kurgu oturum`); const gec = SAYFA.flatMap(([, d, gor]) => adlar.filter((b) => ilkKirilan(b, d) === BICIM[b].adim.length).map((b) => bedel(b, gor))); console.log(`yalnizca son adimda kirilan bilesim: ${gec.length}, gunluk bedeli ` + `${gec.reduce((a, x) => a + x, 0)} kurgu oturum`); const D = [-22, 10, 8, 15, 9, 15]; console.log("\n4. tek katman butun sayfalarda olsaydi"); yaz(D, "tek katman", "yansiyan", "sakli", "belge nesnesi", "mesru", "kalan oturum"); for (const k of KATMAN) { const top = SAYFA.reduce((t, [, , gor]) => t + adlar.reduce((s, b) => s + (k.kirar[b] > 0 ? 0 : bedel(b, gor)), 0), 0); yaz(D, k.ad, k.kirar.yansiyan || "-", k.kirar.sakli || "-", k.kirar.belgeNesnesi || "-", k.mesru, top); } const hepsiAcik = SAYFA.reduce((t, [, , gor]) => t + adlar.reduce((s, b) => s + bedel(b, gor), 0), 0); console.log(`hicbir katman yokken gunluk bedel: ${hepsiAcik} kurgu oturum`);
3 bicim, 6 katman, 8 kurgu sayfa 1. bicim basina zincir bicim adim sunucuda kirabilen teslim yansiyan 5 2 4 baglanti basina sakli 6 3 5 goruntuleme basina belge nesnesi 4 0 3 baglanti basina 2. katman-adim eslemesi katman yer yansiyan sakli belge nesnesi girdi-sozlesmesi sunucu 1 1 - depo-temizleme sunucu - 2 - cikti-kodlama sunucu 2 3 - icerik-politikasi tarayici 4 5 3 istemci-hedef-secimi istemci-kodu - - 2 cerez-bayragi tarayici 5 6 4 sunucu tarafindaki 3 katmanin belge nesnesi tabanli bicimde kirdigi adim sayisi: 0 3. sayfa basina ilk kirilan halka sayfa katman yansiyan sakli belge nesnesi abone-portali.arama 4 1. adim 1. adim 3. adim abone-portali.itiraz 4 1. adim 1. adim 4. adim abone-portali.fatura 3 2. adim 3. adim 3. adim saha-uygulamasi.is-emri 3 1. adim 1. adim 4. adim saha-uygulamasi.saha-notu 1 5. adim 6. adim 4. adim sube-ucu.pano 2 2. adim 3. adim 3. adim sube-ucu.rapor-baglantisi 2 5. adim 6. adim 2. adim yonetim.olcum-arama 0 kirilmiyor kirilmiyor kirilmiyor 24 sayfa-bicim bilesiminin 3 tanesinde hicbir halka kirilmiyor; bu bilesimlerin gunluk bedeli 44 kurgu oturum yalnizca son adimda kirilan bilesim: 7, gunluk bedeli 190 kurgu oturum 4. tek katman butun sayfalarda olsaydi tek katman yansiyan sakli belge nesnesi mesru kalan oturum girdi-sozlesmesi 1 1 - 3 96 depo-temizleme - 2 - 2 192 cikti-kodlama 2 3 - 0 96 icerik-politikasi 4 5 3 7 0 istemci-hedef-secimi - - 2 1 1086 cerez-bayragi 5 6 4 4 0 hicbir katman yokken gunluk bedel: 1182 kurgu oturum
Sunucunun Görmediği Zincir
İkinci tablonun son satırı bu dersin ana bulgusudur: sunucu tarafındaki üç katmanın belge nesnesi tabanlı biçimde kırdığı adım sayısı sıfırdır. Girdi sözleşmesi bir istek görmez, depo temizleme bir yazma görmez, çıktı kodlaması yanıtın içine yazılan bir değer görmez. Değer sunucuya hiç uğramaz.
Bunun ikinci bir sonucu vardır ve ilkinden ağırdır: sunucu bu zincirin hiçbir adımını kaydetmez. Kırılamayan bir zincirde ölçü tespite kayar; burada tespit de sunucu tarafında yapılamaz, çünkü bakılacak bir kayıt satırı yoktur. Bu biçimin görülebileceği tek yerler tarayıcı davranışını raporlayan bir politika ihlali bildirimi ve istemci kodunun kendi kaydıdır.
Aynı satır bir katman sınıfını da öne çıkarır: istemci-hedef-secimi yalnız bu biçimde
değer taşır ve tek başına ikinci adımı kırar. Sunucuyu sertleştirmekle ilgili hiçbir
karar bu adımı etkilemez.
Bu, ölçünün nereye taşındığını da belirler. Bir savunma raporu sunucu tarafındaki üç katmanı sayarak “üç katmanlı koruma” yazabilir ve bu, iki biçim için doğru olur. Üçüncü biçim için sayı üçtür ama kırdığı adım sıfırdır — ve rapor bu ikisini ayırmadığı sürece fark görünmez. Katman saymak yerine kırılan adımı saymanın gerekçesi bu satırdır.
Zincir Uzunluğu ve Teslim
Birinci tablo üç biçimi yan yana koyar: 5, 6 ve 4 adım. En uzun zincir en güvenli olan değildir. Saklı biçim altı adımdır ve bir adım fazlası saldıranın lehinedir: dördüncü adım bir teslim çabası gerektirmez, sayfayı kendi işi için açan herkes o adımı tamamlar.
Kırabilen katman sayısı da aynı yönde okunur: yansıyan biçimi dört katman, saklı biçimi beş, belge nesnesi tabanlı biçimi üç katman kırabiliyor. Saklı biçim en çok katmanın gördüğü biçimdir çünkü en çok adımı sunucudan geçer; en az katmanın gördüğü biçim ise sunucudan hiç geçmeyendir. Bir zincirin görülebilirliği uzunluğuyla değil, savunmanın bulunduğu tarafta kaç adım geçirdiğiyle ölçülür.
Teslim sütunu bedelin de biriminin farklı olduğunu söyler. Yansıyan ve belge nesnesi tabanlı biçimlerde bedel bağlantı başınadır — kurgu 12 kişi. Saklı biçimde bedel görüntüleme başınadır ve sayfaya göre 20 ile 340 arasında değişir. Aynı sınıf, aynı sayfa, farklı biçim: geç kırmanın bedeli yirmi sekiz katına kadar çıkar.
Sayfa Başına Kırılma
Üçüncü tablo dağıtımı ölçer. Sekiz sayfa ve üç biçimin kurduğu 24 bileşimin 3’ünde hiçbir halka kırılmıyor; üçü de tek bir sayfada toplanıyor. O sayfada hiçbir katman dağıtılmamış durumda ve günlük bedeli 44 kurgu oturum.
Daha ince olan sonuç yedi bileşimdedir: oralarda zincir kırılıyor, ama yalnız son adımda. Çerez bayrağı taşıyan ama başka hiçbir katmanı olmayan bir sayfada kod çalışır, sayfa değişir, istekler gider — kırılan tek halka en sondaki erişimdir. Bu yedi bileşimin günlük bedeli 190 oturumdur ve savunma raporunda “korunuyor” diye görünürler.
Tablonun sol sütunu bu sonucun nedenini verir. Dört katmanı olan iki sayfada zincir birinci
adımda kırılıyor; üç katmanı olan sayfalarda ikinci ya da üçüncü adımda; tek katmanı olan
sayfada beşinci ve altıncı adımda. Katman sayısı ile kırılan halkanın indeksi bu kümede
birlikte hareket ediyor, ama birebir değil: üç katmanlı abone-portali.fatura ikinci adımda
kırarken, iki katmanlı sube-ucu.pano da ikinci adımda kırıyor. Belirleyici olan sayı değil,
katmanların hangi adımlara düştüğüdür.
sube-ucu.rapor-baglantisi satırı iki katmanın yön farkını gösterir. Belge nesnesi tabanlı
biçimde zincir ikinci adımda kırılıyor, çünkü istemci hedef seçimi oradadır; yansıyan ve
saklı biçimlerde ise ancak beşinci ve altıncı adımda. Aynı sayfa, aynı iki katman, biçime
göre üç farklı halka.
Tek Katmanın Kapsamı
Dördüncü tablo her katmanı tek başına, bütün sayfalarda varsayar ve geriye kalan günlük bedeli sayar. Hiçbir katman yokken bedel 1.182 kurgu oturumdur.
İki satır sıfır veriyor: içerik politikası ve çerez bayrağı üç biçimi de kırıyor, çünkü ikisi de tarayıcı tarafındadır ve üç biçim de orada birleşir. Meşru işe bedelleri 7 ve 4’tür — üç katmanın en pahalıları.
Depo temizlemenin satırı ise tek biçime bağlı bir katmanın sınırını verir: saklı biçimi ikinci adımda kırar, öteki iki biçimde hiçbir şey yapmaz ve geriye 192 oturum bırakır — altı satırın en yükseği değil ama en dar kapsamlısı.
Çıktı kodlamasının meşru işe bedeli sıfırdır ve yansıyan ile saklı biçimi ikinci ve üçüncü adımda kırar; ama belge nesnesi tabanlı biçimde hiçbir şey yapmaz ve geriye 96 oturum bırakır. En ucuz katman en erken kırar ve en dar kapsar; en pahalı katman en geç kırar ve tam kapsar. Kapsam ile erkenlik aynı katmanda birleşmiyor — bu, iki katmanın da gerekmesinin ölçülmüş nedenidir.
Özet
- Üç biçim üç ayrı zincirdir: yansıyan 5, saklı 6, belge nesnesi tabanlı 4 adım. Saklı biçimin fazladan adımı saldıranın lehinedir, çünkü teslim halkasının önkoşulunu ortadan kaldırır.
- Sunucu tarafındaki 3 katmanın belge nesnesi tabanlı biçimde kırdığı adım sayısı 0’dır ve o zincirin hiçbir adımı sunucu kaydına düşmez; orada ölçü kırmadan tespite kayar, tespit de yalnız tarayıcı tarafında yapılabilir.
- Bedelin birimi biçime göre değişir: bağlantı başına 12 kurgu kişi, görüntüleme başına 20 ile 340 arası. Aynı sayfada geç kırmanın bedeli biçime göre yirmi sekiz katına kadar çıkar.
- Sekiz sayfa ve üç biçimin 24 bileşiminin 3’ünde hiçbir halka kırılmıyor (günlük 44 oturum), 7’sinde yalnız son adımda kırılıyor (günlük 190 oturum).
- Tarayıcı tarafındaki iki katmanın her biri tek başına üç biçimi de kapatıyor ve kalan bedeli 0’a indiriyor; meşru bedelleri 7 ve 4. Bedeli 0 olan çıktı kodlaması en erken kırıyor ama bir biçimi hiç görmediği için geriye 96 oturum bırakıyor.
Sonraki Adım
Bu dersin üç biçiminde de kod kurbanın tarayıcısında çalışıyordu ve son adımda oturum kalemine erişiyordu. Aynı tarayıcının yapabileceği daha sessiz bir şey daha vardır: hiçbir kod çalıştırmadan, yalnız bir isteği kurbanın kimliğiyle göndermek. Sonraki ders bu sınıfı ölçer — isteğin kurbanın tarayıcısı üzerinden gittiği yön ile sunucunun kendi kimliğiyle gittiği yön ayrı zincirler olarak yazılır, her yönün kaç adımı olduğu, hangi katmanın hangi adımı kırdığı ve iki yönün geç kırma bedellerinin neden aynı birimle ölçülemediği sayılır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.