İçeriğe geç
academia.sh

Ders 19 / 27

Üçüncü Taraf Betik Riski

Kendi yazılmayan kodun sayfa kaynağının yetkileriyle çalışması; tedarik zincirinin halkaları, alt kaynak bütünlüğü karmasının üretimi ve doğrulanması, bütünlüğün kapsamı ve çalışma zamanı yalıtımı.

İçindekiler

Önceki dersler uygulamanın kendi kodunu ve kendi sunucusunun yapılandırmasını konu aldı. Kuzey Yamaç Ölçüm İstasyonu arayüzü ise kendi yazmadığı kodu da çalıştırır: ölçüm grafiğini çizen dış betik, sayfaya gömülü harita çerçevesi ve derleme sırasında paketlenen bağımlılık ağacı.

Bu ders o kodun taşıdığı riski ve riski daraltan katmanları kurar. Çıkış noktası tek bir gözlemdir: sayfada çalışan üçüncü taraf betik, uygulamanın kendi betiğinden daha az yetkili değildir.

Devralınan Yetki

İlk derste kurulan yetki kavramı burada yeniden geçerlidir. Bir betik ögesiyle sayfaya alınan kod, belgenin kaynağı içinde çalışır. Aynı kaynak politikası onu yabancı saymaz: belge ağacının tamamını okuyabilir ve değiştirebilir, HttpOnly işaretli olmayan çerezlere erişebilir, yerel depolamayı okuyabilir, kullanıcının oturumuyla istek gönderebilir. Ölçüm notu alanına yazılan metni, kullanıcı gönderme düğmesine basmadan da görebilir.

Bu yetki devri bir kusur değil, betik ögesinin tanımıdır. Kusur, yetkinin farkında olmadan devredilmesidir. “Grafik çizen bir betik” cümlesi, betiğin yalnız grafik çizeceğini söylemez; yalnız o an öyle davrandığını söyler.

Ölçüm grafiği betiği kendi başına iyi niyetli olabilir. Risk, betiğin bugünkü içeriğinin yarın da aynı kalacağı varsayımındadır ve bu varsayım zincirin her halkasında ayrı ayrı sınanmalıdır.

Tedarik Zincirinin Halkaları

Sayfada çalışan kodun kaynağına doğru geriye gidildiğinde birkaç ayrı güven noktası görünür.

Doğrudan bağımlılıklar, geliştiricinin bilerek eklediği paketlerdir; sayıları gözden geçirilebilir düzeydedir. Dolaylı bağımlılıklar, o paketlerin kendi bağımlılıklarıdır ve sayıları hızla büyür. Üretim paketine giren kodun büyük bölümü genellikle bu ikinci kümeden gelir ve hiçbir zaman tek tek okunmamıştır.

Paket kayıt defteri, sürümlerin dağıtıldığı yerdir. Bir sürümün yayımlanması, o paketin bakımcısının hesabına erişimi olan herkesin yapabildiği bir işlemdir. Derleme araçları kendi eklentileriyle birlikte gelir ve derleme aşamasında çalıştırılan kod, üretim paketinin içeriğini belirler.

İçerik dağıtım ağı üzerinden çalışma zamanında yüklenen betikler, zincirin en kırılgan halkasıdır: kod uygulamanın deposunda hiç bulunmaz, sürüm sabitlenmemişse her sayfa yüklemesinde farklı olabilir ve değişiklik hiçbir derleme kaydına düşmez.

Zincirin uzunluğu bir kural doğurur: her halka için “bu içerik değiştiğinde bunu ne haber verir” sorusunun bir yanıtı olmalıdır. Aşağıdaki mekanizma bu soruyu çalışma zamanı halkası için yanıtlar.

Alt Kaynak Bütünlüğü

Alt kaynak bütünlüğü (subresource integrity), bir betik veya biçem ögesine, yüklenecek içeriğin özetini önceden bildirme olanağı verir. Tarayıcı içeriği getirir, özetini hesaplar ve bildirilen değerle karşılaştırır; uyuşmazsa kaynağı kullanmaz.

// butunluk.mjs — alt kaynak butunlugu karmasi uretir ve dogrular
import { createHash } from 'node:crypto';

const BETIK_ILK = 'export function olcumGrafigi(veri) { return veri.map((n) => n.sicaklik); }\n';
const BETIK_DEGISMIS = 'export function olcumGrafigi(veri) { return veri.map((n) => n.sicaklik ?? 0); }\n';

function butunlukDegeri(icerik, algoritma = 'sha384') {
  const karma = createHash(algoritma).update(icerik, 'utf8').digest('base64');
  return `${algoritma}-${karma}`;
}

function dogrula(icerik, beklenenler) {
  const liste = beklenenler.trim().split(/\s+/);
  for (const beklenen of liste) {
    const [algoritma] = beklenen.split('-');
    if (butunlukDegeri(icerik, algoritma) === beklenen) return { gecerli: true, eslesen: beklenen };
  }
  return { gecerli: false, eslesen: null };
}

const bildirilen = `${butunlukDegeri(BETIK_ILK)} ${butunlukDegeri(BETIK_ILK, 'sha512')}`;
console.log('bildirilen integrity degeri:');
console.log(' ', bildirilen.split(' ')[0]);
console.log(' ', bildirilen.split(' ')[1]);

console.log('\nteslim edilen icerik degerlendirmesi:');
for (const [ad, icerik] of [['yayindaki surum', BETIK_ILK], ['degistirilmis surum', BETIK_DEGISMIS]]) {
  const sonuc = dogrula(icerik, bildirilen);
  console.log(' ', ad.padEnd(22), sonuc.gecerli ? 'yuklenir' : 'reddedilir');
}

console.log('\nkarma karsilastirmasi (sha384):');
console.log(' ', 'yayindaki'.padEnd(14), butunlukDegeri(BETIK_ILK).slice(0, 34) + '...');
console.log(' ', 'degistirilmis'.padEnd(14), butunlukDegeri(BETIK_DEGISMIS).slice(0, 34) + '...');
$ node butunluk.mjs
bildirilen integrity degeri:
  sha384-ZkRpwsatJjtybxkzgNKSmNTOnRaRUzSzw9F6JovPGdvv5p8LDezsXzf1oQJwgSSa
  sha512-csD06cIQYqXhn6nHO3g1ZVsnr7JYYDUqLYC/8fr2S3YiuOXbxS71oHDXxSCYlr2vntrI5NJPZrw9djvCNy5Zww==

teslim edilen icerik degerlendirmesi:
  yayindaki surum        yuklenir
  degistirilmis surum    reddedilir

karma karsilastirmasi (sha384):
  yayindaki      sha384-ZkRpwsatJjtybxkzgNKSmNTOnRa...
  degistirilmis  sha384-FVN8BPXsL5tcc6wAQtU46Q0KIEA...

İki sürüm arasındaki fark tek bir işleçtir; karmaların başlangıcı bile ortak değildir. Özet işlevinin bu davranışı mekanizmanın tamamını taşır: içerikte tek karakter değişirse karma tanınmaz hâle gelir ve doğrulama kalır.

Bildirilen değer birden çok karma taşıyabilir. Tarayıcı desteklediği en güçlü algoritmayı seçer; bir algoritmanın gelecekte güvenilmez sayılması durumunda liste, ögeyi değiştirmeden geçişe olanak verir.

İki gerçekleştirme kuralı bağlayıcıdır. Birincisi, kaynaklar arası yüklenen bir öge için crossorigin özniteliği gerekir; bütünlük denetimi, içeriği okunamayan saydam bir yanıt üzerinde yapılamaz. İkincisi, karmanın bir anlamı olması için adresin sürümlenmiş olması gerekir. “En son sürüm” anlamına gelen bir adres, sağlayıcı içeriği güncellediğinde doğrulamayı kırar; bu kırılma bir kusur değil, mekanizmanın çalıştığının kanıtıdır — ama uygulamanın çalışmayı sürdürmesi isteniyorsa adresin sabit olması gerekir.

Bütünlüğün Kapsamadığı Alan

Bütünlük denetimi, yüklenen baytların beklenen baytlar olduğunu doğrular. O baytların ne yaptığını doğrulamaz. Sağlayıcı yeni bir sürüm yayımlar, uygulama yeni karmayı bildirir ve yeni sürüm ilk sürümün yapmadığı bir şey yapıyorsa denetim hiçbir uyarı üretmez.

Denetim ayrıca yalnız bildirilen ögeyi kapsar. Yüklenen betiğin kendisi çalışma zamanında başka betikler getiriyorsa, o getirmeler bu ögeye bağlı değildir. İçerik güvenlik politikasının kaynak listeleri bu boşluğun bir bölümünü kapatır: bütünlük “bu adresten ne geleceğini” sabitler, politika “hangi adreslerden yükleme yapılabileceğini” sınırlar. İki mekanizma birbirinin yerine geçmez.

Çalışma Zamanında Eklenen Kod

Bir sınıf araç, sayfaya betik eklemeyi kod değişikliğinden ayırır: bir yönetim arayüzünden tanımlanan kod parçaları, uygulamanın yükleyicisi tarafından çalışma zamanında sayfaya alınır. Ölçüm istasyonunda bu yolla eklenen bir kullanım ölçüm betiği, uygulamanın deposunda hiç görünmez.

Bu düzenlemenin güvenlik açısından iki sonucu vardır. Birincisi, sayfada çalışan kodun kümesi artık depodan okunamaz; envanter ancak çalışan sayfadan çıkarılabilir. İkincisi, sayfaya kod ekleme yetkisi, kod gözden geçirmesinden geçmeyen bir gruba açılmıştır ve o grubun hesap güvenliği uygulamanın güvenliğinin parçası hâline gelir.

Daraltma yolları üçtür. İçerik güvenlik politikasının kaynak listeleri yükleyicinin getirebileceği adresleri sınırlar; bu, aracı bir yükleme noktası olmaktan çıkarmaz ama sınırsız olmaktan çıkarır. Politikanın rapor kipiyle toplanan ihlal kayıtları, beklenmeyen bir yükleme noktasını görünür kılar. Üçüncüsü yönetimseldir: sayfada çalışan üçüncü taraf kodun listesi yazılı tutulur, her kalem bir sahiple ve bir gerekçeyle eşleşir, gerekçesi kalmayan kalem kaldırılır. Envanteri olmayan bir sayfada bu dersteki hiçbir önlem tamamlanmış sayılmaz.

Yalıtım ve Derleme Zamanı Önlemleri

Bir üçüncü taraf bileşenin sayfada arayüz göstermesi gerekiyorsa, betik ögesi yerine ayrı bir kaynaktan yüklenen bir çerçeve kullanmak yetki devrini keser. Web’in Temelleri ve HTML kursunda tanıtılan yalıtım (sandboxing) öznitelikleri, çerçevenin hangi yetenekleri kullanabileceğini sayar; yetenek izni başlığı aygıt erişimini daraltır. İletişim, ana belgeyle çerçeve arasında dar bir ileti arayüzü üzerinden kurulur ve gelen iletiler gönderen kaynağına göre doğrulanır. Harita çerçevesi bu yapının tipik örneğidir: haritanın ölçüm notlarını okuması için hiçbir neden yoktur ve çerçeve bunu yapısal olarak engeller.

Derleme zamanı tarafında dört önlem birlikte çalışır. Kilit dosyası, çözümlenmiş sürümleri ve içerik özetlerini deponun içine yazar; kilit dosyasını yok sayan bir kurulum, bu savunmanın tamamını devre dışı bırakır. Sürüm sabitleme, bir sonraki kurulumun aynı kodu getirmesini sağlar. Bilinen açık taraması, bağımlılıklardaki yayımlanmış açık kayıtlarını kurulumla eşler. Paket içeriğinin ölçülmesi, üretim paketine giren kodun boyutunu ve bileşimini görünür kılar; bir bağımlılığın beklenmedik biçimde büyümesi çoğu zaman ilk sinyaldir.

Son bir önlem yönetimseldir: yeni bir bağımlılık eklemek bir kod değişikliğidir ve aynı gözden geçirmeden geçer. Bir işlevi kendi yazmakla bir paket eklemek arasındaki seçim, satır sayısı karşılaştırması değil, güven yüzeyi kararıdır.

Özet

  • Sayfaya betik ögesiyle alınan üçüncü taraf kod, uygulamanın kaynağının bütün yetkilerini devralır; belge ağacına, çerezlere ve ağa erişimi kendi kodundan farksızdır.
  • Tedarik zinciri doğrudan ve geçişli bağımlılıklar, kayıt defteri, derleme araçları ve dağıtım ağından oluşur; her halka için değişikliği haber veren bir mekanizma gerekir.
  • Alt kaynak bütünlüğü, yüklenecek içeriğin özetini önceden bildirir; tek karakterlik bir değişiklik karmayı tanınmaz kılar ve kaynak kullanılmaz.
  • Bütünlük baytları doğrular, davranışı doğrulamaz ve yalnız bildirilen ögeyi kapsar; politikanın kaynak listeleriyle birlikte kullanılır.
  • Arayüz gösteren üçüncü taraf bileşen ayrı kaynaktan yüklenen yalıtılmış bir çerçeveye taşınır; derleme tarafında kilit dosyası, sürüm sabitleme, açık taraması ve paket ölçümü birlikte çalışır.

Sonraki Adım

Bu konudaki altı ders belirli mekanizmalara odaklandı: kaçırma, politika, paylaşım başlıkları, istek belirteci, güvenlik başlıkları ve bütünlük. Uygulamada karşılaşılan açıkların çoğu bu mekanizmaların kapsadığı sınıflara girer, ama hepsi girmez. Sonraki ders sık görülen açık sınıflarını istemci tarafındaki izdüşümleriyle ele alır: arayüzde verilen yetki kararları, adres yönlendirmeleri ve istemciye ulaşan veriye duyulan güven.

İ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