Web geliştiricileri için Site İzolasyonu

Masaüstü Chrome 67'nin Site İzolasyonu adlı yeni bir özelliği varsayılan olarak etkindir. Bu makalede, Site İzolasyonu'nun ne hakkında olduğu, neden gerekli olduğu ve web geliştiricilerin bundan neden haberdar olması gerektiği açıklanmaktadır.

Site İzolasyonu nedir?

İnternet, kedi videoları izlemek ve kripto para cüzdanlarını yönetmek için kullanılıyor. Ancak fluffycats.example sitesinin değerli kripto paralarınıza erişmesini istemezsiniz! Neyse ki, Same-Origin Politikası sayesinde web siteleri genellikle tarayıcı içinde birbirlerinin verilerine erişemezler. Yine de kötü amaçlı web siteleri, diğer web sitelerine saldırmak için bu politikayı atlatmaya çalışabilir ve bazen Aynı Kaynak Politikası'nı uygulayan tarayıcı kodunda güvenlik hataları bulunabilir. Chrome ekibi bu tür hataları mümkün olan en kısa sürede düzeltmeyi amaçlar.

Site İzolasyonu, bu tür saldırıların başarılı olma ihtimalini azaltmak için ek bir savunma hattı sunan, Chrome'daki bir güvenlik özelliğidir. Farklı web sitelerindeki sayfaların her zaman farklı işlemlere uygulanmasını sağlar ve her biri işlemin yapmasına izin verilen korumalı alanda çalışır. Ayrıca işlemin başka sitelerden belirli türde hassas verileri almasını da engeller. Sonuç olarak, Site İzolasyonu sayesinde kötü amaçlı bir web sitesinin Spectre gibi spekülatif yan kanal saldırılarını kullanarak diğer sitelerden veri çalması çok daha zordur. Chrome ekibi ek yaptırımları bitirdikçe Site İzolasyonu, bir saldırganın sayfası kendi işleminde bazı kuralları çiğnenebilse bile Site İzolasyonu'na da yardımcı olur.

Site İzolasyonu, güvenilmeyen web sitelerinin diğer web sitelerindeki hesaplarınıza ait bilgilere erişmesini veya bu bilgileri çalmasını etkili bir şekilde zorlaştırır. Yakın zamanda gerçekleşen Meltdown ve Spectre yan kanal saldırıları gibi çeşitli güvenlik hatalarına karşı ek koruma sunar.

Site İzolasyonu hakkında daha fazla bilgi için Google Güvenlik blogundaki makalemize bakın.

Kaynaklar Arası Okuma Engelleme

Tüm siteler arası sayfalar ayrı işlemlere tabi tutulsa bile, sayfalar yasal olarak resimler ve JavaScript gibi bazı siteler arası alt kaynaklar için istekte bulunabilir. Kötü amaçlı bir web sayfası, banka bakiyeniz gibi hassas veriler içeren bir JSON dosyası yüklemek için <img> öğesi kullanabilir:

<img src="https://your-bank.example/balance.json" />
<!-- Note: the attacker refused to add an `alt` attribute, for extra evil points. -->

Site İzolasyonu kullanılmadığında, JSON dosyasının içeriği oluşturucu işleminin belleğine gider. Bu noktada oluşturucu, bunun geçerli bir resim biçimi olmadığını fark eder ve bir resim oluşturmaz. Ancak saldırgan, bu bellek parçasını potansiyel olarak okumak için Spectre gibi bir güvenlik açığından yararlanabilir.

Saldırgan, hassas verileri belleğe işlemek için <img> kullanmak yerine <script> kullanabilir:

<script src="https://your-bank.example/balance.json"></script>

Çapraz Kaynak Okuma Engelleme veya CORB, balance.json içeriğinin, MIME türüne göre oluşturucu işlem belleğinin belleğine girmesini engelleyen yeni bir güvenlik özelliğidir.

CORB'ın işleyiş şeklini inceleyelim. Bir web sitesi, bir sunucudan iki tür kaynak isteyebilir:

  1. HTML, XML veya JSON dokümanları gibi veri kaynakları
  2. resimler, JavaScript, CSS veya yazı tipleri gibi medya kaynakları

Bir web sitesi, kendi kaynağından veya Access-Control-Allow-Origin: * gibi serbest CORS başlıklarına sahip diğer kaynaklardan veri kaynakları alabilir. Diğer yandan, medya kaynakları, uygun CORS başlıkları olmasa bile herhangi bir kaynaktan eklenebilir.

CORB, aşağıdaki durumlarda oluşturucu işleminin kaynaklar arası veri kaynağı (ör. HTML, XML veya JSON) almasını engeller:

  • kaynağın X-Content-Type-Options: nosniff başlığı var
  • CORS, kaynağa erişime açıkça izin vermez.

Kaynaklar arası veri kaynağında X-Content-Type-Options: nosniff üst bilgisi ayarlanmamışsa CORB, HTML, XML veya JSON olup olmadığını belirlemek için yanıt gövdesini yoklamaya çalışır. Örneğin, bazı web sunucuları yanlış yapılandırıldığından ve resimleri text/html olarak sunduğundan bu gereklidir.

CORB politikası tarafından engellenen veri kaynakları işleme boş olarak sunulur ancak istek yine de arka planda gerçekleşir. Sonuç olarak, kötü amaçlı bir web sayfası çalmak için siteler arası verileri işleme sürecine sokmakta zorlanır.

Optimum güvenlik için ve CORB'dan yararlanmak için aşağıdakileri öneririz:

  • Yanıtları doğru Content-Type üstbilgisiyle işaretleyin. (Örneğin HTML kaynakları text/html, JSON MIME türüne sahip JSON kaynakları ve XML MIME türüne sahip XML kaynakları olarak sunulmalıdır.)
  • X-Content-Type-Options: nosniff başlığını kullanarak yoklama özelliğini devre dışı bırakın. Bu başlık olmadan, Chrome, türün doğru olduğunu onaylamak için hızlı bir içerik analizi yapar, ancak bu, JavaScript dosyaları gibi öğeleri engellemekten kaçınmak için yanıtlara izin vermek anlamına geldiğinden, onaylayarak doğru olanı sizin yapmanız daha iyi olur.

Daha fazla bilgiyi Web geliştiricileri için CORB makalemizde veya ayrıntılı CORB açıklamamızda bulabilirsiniz.

Web geliştiricileri Site İzolasyonu'na neden önem vermelidir?

Çoğunlukla, Site İzolasyonu web geliştiricilerine doğrudan sunulmayan, perde arkası bir tarayıcı özelliğidir. Örneğin, öğrenebileceğiniz, web'de kullanıma sunulan yeni bir API yoktur. Genel olarak web sayfaları, Site İzolasyonu ile veya bu uygulama olmadan çalışırken farkı ayırt edememelidir.

Ancak, bu kuralın bazı istisnaları vardır. Site İzolasyonu'nun etkinleştirilmesi, web sitenizi etkileyebilecek birkaç küçük yan etkiyle birlikte gelir. Bilinen Site İzolasyonu sorunlarının bir listesini sağlıyoruz ve en önemlilerini aşağıda ayrıntılı olarak açıklıyoruz.

Tam sayfa düzeni artık eşzamanlı değil

Site İzolasyonu sayesinde, bir sayfanın çerçeveleri artık birden fazla işleme yayılabileceğinden tam sayfa düzeninin eşzamanlı olacağı artık garanti edilmez. Bu durum, bir düzen değişikliğinin sayfadaki tüm karelere hemen yayıldığını varsayarsa sayfaları etkileyebilir.

Örneğin, social-widget.example üzerinde barındırılan bir sosyal widget ile iletişim kuran fluffykittens.example adlı bir web sitesini ele alalım:

<!-- https://fluffykittens.example/ -->
<iframe src="https://social-widget.example/" width="123"></iframe>
<script>
  const iframe = document.querySelector('iframe');
  iframe.width = 456;
  iframe.contentWindow.postMessage(
    // The message to send:
    'Meow!',
    // The target origin:
    'https://social-widget.example'
  );
</script>

Sosyal medya widget'ının <iframe> genişliği ilk başta 123 pikseldir. Ancak ardından FluffyKittens sayfası, genişliği 456 piksel olarak değiştirir (tetikleyici düzen) ve aşağıdaki koda sahip olan sosyal widget'a bir mesaj gönderir:

<!-- https://social-widget.example/ -->
<script>
  self.onmessage = () => {
    console.log(document.documentElement.clientWidth);
  };
</script>

Sosyal widget, postMessage API üzerinden bir mesaj aldığında kök <html> öğesinin genişliğini günlüğe kaydeder.

Hangi genişlik değeri günlüğe kaydedilir? Chrome, Site İzolasyonu etkinleştirilmeden önce cevap 456 idi. document.documentElement.clientWidth alanına erişim, Chrome'un etkin olduğu Site İzolasyonu'ndan önce eşzamanlı olan düzeni zorlar. Ancak Site İzolasyonu etkinleştirildiğinde, kaynaklar arası sosyal widget yeniden yerleşimi artık eşzamansız olarak ayrı bir işlemde gerçekleşmektedir. Bu nedenle, yanıt artık 123, yani eski width değeri de olabilir.

Bir sayfa, çapraz kaynak <iframe> boyutunun boyutunu değiştirir ve sonra ona bir postMessage gönderirse Site İzolasyonu ile alıcı çerçeve mesajı alırken yeni boyutunu henüz bilmiyor olabilir. Daha genel olarak bu durum, bir düzen değişikliğinin sayfadaki tüm çerçevelere hemen yayıldığı varsayılırsa sayfaları bozabilir.

Bu örnekte, daha güçlü bir çözüm, width üst çerçevede ayarlanır ve bir resize etkinliğini dinleyerek <iframe> içindeki bu değişikliği algılar.

Kaldırma işleyicileri daha sık zaman aşımına uğrayabilir

Bir çerçeve gezindiğinde veya kapandığında, eski dokümanın ve içine yerleştirilmiş tüm alt çerçeve dokümanlarının unload işleyicisini çalıştırır. Yeni gezinme aynı oluşturucu sürecinde gerçekleşirse (ör. aynı kaynakta gezinme için) eski belgenin ve alt çerçevelerinin unload işleyicileri, yeni gezinmenin kaydedilmesine izin vermeden önce rastgele uzun bir süre çalışabilir.

addEventListener('unload', () => {
  doSomethingThatMightTakeALongTime();
});

Bu durumda, tüm karelerdeki unload işleyicileri son derece güvenilirdir.

Ancak Site İzolasyonu kullanılmasa bile bazı ana çerçeve gezinmeleri çapraz işlemlerdir ve bu da kaldırma işleyici davranışını etkiler. Örneğin, old.example konumundan new.example konumuna URL'yi adres çubuğuna yazarak giderseniz new.example gezinmesi yeni bir süreçte gerçekleşir. old.example için kaldırma işleyicileri ve alt çerçeveleri, new.example sayfası gösterildikten sonra arka planda old.example işleminde çalışır. Eski kaldırma işleyicileri de belirli bir zaman aşımı süresi içinde bitmezse sonlandırılır. Kaldırma işleyicileri zaman aşımına uğramadan önce tamamlanmayabileceğinden kaldırma davranışı daha az güvenilirdir.

Site İzolasyonu ile tüm siteler arası gezinmeler çapraz işlem haline gelir. Böylece farklı sitelerden alınan belgeler bir süreci birbirleriyle paylaşmaz. Sonuç olarak yukarıdaki durum daha fazla durum için geçerlidir ve <iframe>'lerdeki kaldırma işleyicileri genellikle yukarıda açıklanan arka plan ve zaman aşımı davranışlarına sahiptir.

Site İzolasyonu'ndan kaynaklanan bir başka fark da kaldırma işleyicilerinin yeni paralel sıralamasıdır: Site İzolasyonu olmadan, kaldırma işleyicileri çerçeveler arasında tam bir yukarıdan aşağıya sırayla çalışır. Ancak Site Yalıtımı ile kaldırma işleyicileri farklı süreçlerde paralel olarak çalışır.

Bunlar, Site İzolasyonu'nun etkinleştirilmesinin temel sonuçlarıdır. Chrome ekibi, yaygın kullanım alanları için kaldırma işleyicilerinin güvenilirliğini mümkün olduğunca iyileştirmek üzere çalışmaktadır. Ayrıca alt çerçeve kaldırma işleyicilerin henüz belirli özellikleri kullanamadığı hataların farkındayız ve bunları çözmek için çalışıyoruz.

Kaldırma işleyicileri için önemli bir durum, oturum sonu ping'leri göndermektir. Bu genellikle şu şekilde yapılır:

addEventListener('pagehide', () => {
  const image = new Image();
  img.src = '/end-of-session';
});

Bu değişiklik ışığında daha güçlü olan daha iyi bir yaklaşım, bunun yerine navigator.sendBeacon kullanmaktır:

addEventListener('pagehide', () => {
  navigator.sendBeacon('/end-of-session');
});

İstek üzerinde daha fazla kontrole ihtiyacınız varsa Fetch API'sinin keepalive seçeneğini kullanabilirsiniz:

addEventListener('pagehide', () => {
  fetch('/end-of-session', {keepalive: true});
});

Sonuç

Site İzolasyonu, her siteyi kendi işleminde izole ederek güvenilmeyen web sitelerinin diğer web sitelerindeki hesaplarınızdaki bilgilere erişmesini veya bu bilgileri çalmasını zorlaştırır. Bunun bir parçası olarak CORB, hassas veri kaynaklarını oluşturucu işleminin dışında tutmaya çalışır. Yukarıdaki önerilerimiz, bu yeni güvenlik özelliklerinden en iyi şekilde yararlanmanızı sağlar.

Bu makalenin taslak sürümünü okudukları ve geri bildirimlerini paylaştıkları için Alex Moshchuk, Charlie Reis, Jason Miller, Nasko Oskov, Philip Walton, Shubhie Panicker ve Thomas Steiner'a teşekkür ederiz.