İçeriğe geç
academia.sh

Ders 18 / 27

Güvenlik Başlıkları

Taşıma güvenliğinin zorlanması, çerçevelemenin sınırlanması, referans bilgisinin daraltılması, tür tahmininin kapatılması ve kaynak yalıtımı; eksikleri bulan bir yapılandırma denetleyicisi.

İçindekiler

Önceki üç ders belirli saldırı sınıflarına karşı belirli katmanlar kurdu. Bu ders, tek bir sınıfa bağlı olmayan ama hepsinin etkisini azaltan bir kümeyi ele alır: yanıt başlıklarıyla bildirilen ve tarayıcının uyguladığı kısıtlar.

Bu başlıkların ortak özelliği, uygulama kodunda değil sunucu yapılandırmasında yaşamalarıdır. Bir sürüm çıkarken gözden kaçmaları kolaydır, çünkü hiçbir işlevi bozmazlar; yokluklarının gözlenebilir sonucu yalnız bir şeyler ters gittiğinde ortaya çıkar. Dersin sonundaki denetleyici bu görünmezliği giderir.

Taşıma Güvenliğinin Zorlanması

İnternet Nasıl Çalışır kursundaki HTTPS’in Rolü dersi şifreli taşımanın gizlilik, bütünlük ve kimlik doğrulama sağladığını kurmuştu. Uygulama tümüyle şifreli sunuluyor olsa bile bir boşluk kalır: kullanıcı adresi şemasız yazdığında ilk istek şifresiz gidebilir ve yönlendirmeden önce araya girilebilir.

Strict-Transport-Security başlığı bu boşluğu kapatır. Tarayıcıya, bildirilen süre boyunca bu konağa yalnız şifreli bağlanmasını söyler; şemasız yazılan adres ağa çıkmadan dönüştürülür. Üç bileşeni vardır. max-age sürenin saniye cinsinden uzunluğudur ve anlamlı bir koruma için uzun tutulur. includeSubDomains kuralı alt alanlara yayar; bu olmadan bir alt alan şifresiz kalabilir ve çerez kapsamı üzerinden uygulamayı etkiler. Üçüncü bileşen, konağı tarayıcılara gömülü listeye kaydeden ön yükleme bildirimidir; ilk isteği de kapsar, ama geri alınması yavaştır ve tüm alt alanların şifreli sunulmasını kalıcı olarak taahhüt eder.

Başlığın şifresiz bir yanıtta gönderilmesinin bir etkisi yoktur ve olmamalıdır: aksi takdirde araya giren biri, konağı erişilemez kılan bir kayıt yazdırabilirdi.

Çerçevelemenin Sınırlanması

Kuzey Yamaç Ölçüm İstasyonu arayüzü, istasyon konumunu gösteren bir harita çerçevesi gömer. Bu, çerçevelemenin bir yönüdür. Öteki yön, uygulamanın kendisinin başka bir sayfa tarafından çerçevelenmesidir ve savunma gerektiren yön budur.

Görünmez kılınmış bir çerçeve içine alınan bir sayfa, kullanıcının gördüğü başka bir arayüzün altında durur. Kullanıcı gördüğü düğmeye tıkladığını sanırken çerçeve içindeki sayfanın bir denetimine tıklar; oturum kendisine ait olduğu için işlem gerçekleşir. Bu sınıfın adı tıklama hırsızlığıdır (clickjacking) ve savunması, belgenin kimler tarafından çerçevelenebileceğini bildirmektir.

İki mekanizma vardır. X-Frame-Options başlığı DENY veya SAMEORIGIN değerlerini alır ve tek bir karar bildirir. İçerik güvenlik politikasının frame-ancestors yönergesi ise kaynak listesi kabul eder ve daha ayrıntılıdır: yalnız belirli kaynakların çerçevelemesine izin verilebilir. Yönergeyi anlayan bir gerçekleştirimde yönerge kazanır; ikisini birlikte yazmak, yalnız birini anlayan gerçekleştirimlerde de koruma sağlar.

Referans Bilgisinin Daraltılması

Bir bağa tıklandığında veya bir alt kaynak yüklendiğinde tarayıcı, isteğe hangi sayfadan gelindiğini bildiren bir başlık ekler. Öntanımlı davranış, tam adresi göndermeye kadar gidebilir. Ölçüm istasyonunda bu, .../istasyon/kuzey-yamac?olcum=4417 biçimindeki bir adresin yol ve sorgu bileşenlerinin üçüncü bir tarafa sızması demektir.

Referrer-Policy başlığı bu davranışı daraltır. Değerler bir eksen üzerinde durur: hiçbir şey göndermeyen uçtan, tam adresi gönderen uca kadar. Dengeli seçim, aynı kaynağa tam adresi, başka kaynaklara yalnız kaynak dizgisini gönderen ve şifreliden şifresize geçişte hiçbir şey göndermeyen değerdir. Analiz ihtiyacı bu bilgiyi gerektiriyorsa, bilgi başlıktan değil uygulamanın kendi ölçümünden alınır.

Tür Tahmininin Kapatılması

Bir yanıtın içerik türü eksik veya yanlışsa, tarayıcı gövdeye bakıp türü tahmin edebilir. Kullanıcıların dosya yüklediği bir uygulamada bu tahmin bir açığa dönüşür: metin olarak sunulmak istenen bir yükleme, işaretleme gibi yorumlanırsa aynı kaynakta belge olarak çalışır.

X-Content-Type-Options: nosniff başlığı tahmini kapatır ve tarayıcıyı bildirilen türe uymaya zorlar. Başlık tek başına yetmez; bildirilen türün doğru olması, kullanıcı yüklemelerinin ayrı bir kaynaktan sunulması ve indirme olarak işaretlenmesi aynı savunmanın parçalarıdır.

Kaynak Yalıtımı ve Yetenek İzni

Cross-Origin-Resource-Policy başlığı, bir kaynağın başka kaynaklarca gömülüp gömülemeyeceğini bildirir. Değeri same-origin olduğunda, kaynak yalnız kendi kaynağının belgelerinde kullanılabilir. Bu, verinin başka bir belgenin bellek alanına çekilmesini sınırlayan bir kısıttır.

Aynı ailede iki başlık daha bulunur: belgenin açtığı ve kendisini açan pencerelerle tarayıcı bağlamı paylaşımını kesen başlık ve gömülen kaynakların açık izin bildirmesini zorunlu kılan başlık. İkisi birlikte kaynak yalıtımı (cross-origin isolation) adı verilen durumu kurar. Bu durum bazı yeteneklerin ön koşuludur ve yeteneklerin kullanılmadığı bir uygulamada zorunlu değildir; gereksiz yere açıldığında meşru gömme işlemlerini kırar.

Web’in Temelleri ve HTML kursunda tanıtılan yetenek izni (permission policy) ise ayrı bir eksendir: belgenin ve gömdüğü çerçevelerin hangi aygıt yeteneklerini kullanabileceğini sayar. Harita çerçevesinin konum yeteneğine ihtiyacı yoksa, çerçeveye o yetenek verilmez.

Yapılandırmayı Denetlemek

Bu başlıkların hepsi tek tek doğru yazılabilir ve bir sürüm sonra biri düşebilir. Denetimi kural kümesine dönüştürmek, düşen başlığı görünür kılar.

// basliklar.mjs — yanit basliklarini kural kumesine gore denetler
const BIR_YIL = 31536000;

const KURALLAR = [
  {
    ad: 'tasima guvenligi',
    denetle: (b) => {
      const deger = b['strict-transport-security'];
      if (!deger) return 'Strict-Transport-Security yok';
      const sure = Number(/max-age=(\d+)/.exec(deger)?.[1] ?? 0);
      if (sure < BIR_YIL) return `max-age ${sure} saniye, bir yildan kisa`;
      if (!/includeSubDomains/i.test(deger)) return 'includeSubDomains yok, alt alanlar disarida';
      return null;
    },
  },
  {
    ad: 'icerik guvenlik politikasi',
    denetle: (b) => {
      const deger = b['content-security-policy'];
      if (!deger) return 'Content-Security-Policy yok';
      if (/script-src[^;]*'unsafe-inline'/.test(deger)) return "script-src icinde 'unsafe-inline' var";
      if (!/frame-ancestors/.test(deger)) return 'frame-ancestors yonergesi yok';
      return null;
    },
  },
  {
    ad: 'cerceveleme',
    denetle: (b) =>
      b['x-frame-options'] || /frame-ancestors/.test(b['content-security-policy'] ?? '')
        ? null
        : 'cerceveleme sinirlanmamis',
  },
  {
    ad: 'tur tahmini',
    denetle: (b) => (b['x-content-type-options'] === 'nosniff' ? null : 'X-Content-Type-Options: nosniff yok'),
  },
  {
    ad: 'referans politikasi',
    denetle: (b) => {
      const deger = b['referrer-policy'];
      if (!deger) return 'Referrer-Policy yok';
      const gevsek = ['unsafe-url', 'no-referrer-when-downgrade', 'origin-when-cross-origin'];
      return gevsek.includes(deger) ? `gevsek deger: ${deger}` : null;
    },
  },
  {
    ad: 'kaynak paylasim politikasi',
    denetle: (b) => (b['cross-origin-resource-policy'] ? null : 'Cross-Origin-Resource-Policy yok'),
  },
  {
    ad: 'oturum cerezi',
    denetle: (b) => {
      const deger = b['set-cookie'];
      if (!deger) return null;
      const eksik = ['HttpOnly', 'Secure', 'SameSite'].filter((n) => !new RegExp(n, 'i').test(deger));
      return eksik.length ? `cerez nitelikleri eksik: ${eksik.join(', ')}` : null;
    },
  },
];

function denetle(ad, basliklar) {
  const bulgular = KURALLAR.map((k) => [k.ad, k.denetle(basliklar)]).filter(([, b]) => b !== null);
  console.log(`\n${ad}: ${bulgular.length} bulgu`);
  for (const [kural, bulgu] of bulgular) console.log('  -', `${kural}:`, bulgu);
  if (bulgular.length === 0) console.log('  - bulgu yok');
}

const ilkYayin = {
  'content-type': 'text/html; charset=utf-8',
  'strict-transport-security': 'max-age=86400',
  'content-security-policy': "default-src 'self'; script-src 'self' 'unsafe-inline'",
  'referrer-policy': 'unsafe-url',
  'set-cookie': 'olcum_oturum=abc; Path=/',
};

const duzeltilmis = {
  'content-type': 'text/html; charset=utf-8',
  'strict-transport-security': 'max-age=31536000; includeSubDomains',
  'content-security-policy': "default-src 'self'; script-src 'self' 'nonce-r4k2'; frame-ancestors 'none'",
  'x-frame-options': 'DENY',
  'x-content-type-options': 'nosniff',
  'referrer-policy': 'strict-origin-when-cross-origin',
  'cross-origin-resource-policy': 'same-origin',
  'set-cookie': 'olcum_oturum=abc; Path=/; HttpOnly; Secure; SameSite=Lax',
};

denetle('ilk yayin', ilkYayin);
denetle('duzeltilmis yapilandirma', duzeltilmis);
$ node basliklar.mjs

ilk yayin: 7 bulgu
  - tasima guvenligi: max-age 86400 saniye, bir yildan kisa
  - icerik guvenlik politikasi: script-src icinde 'unsafe-inline' var
  - cerceveleme: cerceveleme sinirlanmamis
  - tur tahmini: X-Content-Type-Options: nosniff yok
  - referans politikasi: gevsek deger: unsafe-url
  - kaynak paylasim politikasi: Cross-Origin-Resource-Policy yok
  - oturum cerezi: cerez nitelikleri eksik: HttpOnly, Secure, SameSite

duzeltilmis yapilandirma: 0 bulgu
  - bulgu yok

İlk yapılandırmanın kusurları tek tek küçüktür ve hiçbiri uygulamayı bozmaz: taşıma kuralının süresi kısadır, politika satır içi koda izin verir, çerçeveleme sınırlanmamıştır, oturum çerezi üç niteliğini de taşımaz. Bulgu listesi bunları tek bir çalıştırmada görünür kılar.

Bu denetimin değeri, sürekli çalıştırılmasındadır. Yayın öncesi bir adım olarak çalıştırıldığında, başlık düşüren bir yapılandırma değişikliği kendini bir sonraki güvenlik gözden geçirmesinde değil, aynı gün gösterir. Kural kümesi de zamanla değişir; yeni bir kural eklendiğinde bulgu listesinin uzaması beklenen davranıştır.

Özet

  • Güvenlik başlıkları sunucu yapılandırmasında yaşar ve eksiklikleri hiçbir işlevi bozmadığı için sessizce oluşur.
  • Strict-Transport-Security ilk istek boşluğunu kapatır; includeSubDomains olmadan alt alanlar korumasız kalır.
  • Çerçeveleme X-Frame-Options veya frame-ancestors yönergesiyle sınırlanır; ikincisi kaynak listesi kabul ettiği için daha ayrıntılıdır.
  • Referrer-Policy yol ve sorgu bilgisinin dışarı sızmasını daraltır; X-Content-Type-Options: nosniff tür tahminini kapatır.
  • Başlık kümesini denetleyen bir kural çözümleyicisi, düşen bir başlığı aynı gün görünür kılar; denetim yayın akışının bir adımı olarak çalıştırılır.

Sonraki Adım

Buraya kadarki savunmalar uygulamanın kendi kodu ve kendi sunucusu üzerinde kuruldu. Ölçüm arayüzü ise kendi yazmadığı kodu da çalıştırır: harita çerçevesi, ölçüm grafiğini çizen dış betik, bağımlılık ağacındaki yüzlerce paket. Bu kodun her satırı, uygulamanın kaynağının yetkileriyle çalışır. Sonraki ders üçüncü taraf kodun oluşturduğu riski, tedarik zinciri boyunca nerede oluştuğunu ve alt kaynak bütünlüğü ile nasıl daraltılabileceğini ele alır.

İ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