Masaüstünde Chrome 67'de Site İzolasyonu adlı yeni bir özellik varsayılan olarak etkindir. Bu makalede Site İzolasyonunun ne olduğu, neden gerekli olduğu ve web geliştiricilerinin neden bundan haberdar olması gerektiği açıklanmaktadır.
Site izolasyonu nedir?
İnternette kedi videoları izleyebilir ve kripto para cüzdanlarını yönetebilirsiniz. Ancak fluffycats.example
'nin değerli kripto paralarınıza erişmesini istemezsiniz. Neyse ki web siteleri, aynı kaynak politikası sayesinde genellikle tarayıcıda birbirlerinin verilerine erişemez. Yine de kötü amaçlı web siteleri, diğer web sitelerine saldırmak için bu politikayı atlatmaya çalışabilir. Ayrıca, aynı kaynak politikasını uygulayan tarayıcı kodunda zaman zaman güvenlik hataları bulunur. Chrome ekibi bu tür hataları mümkün olduğunca hızlı bir şekilde düzeltmeyi amaçlamaktadır.
Site İzolasyonu, Chrome'daki bir güvenlik özelliğidir. Bu özellik, bu tür saldırıların başarılı olma olasılığını azaltmak için ek bir savunma hattı sunar. Bu özellik, farklı web sitelerindeki sayfaların her zaman farklı işlemlere yerleştirilmesini sağlar. Bu işlemler, her biri işlemin yapabileceği işlemleri sınırlayan bir korumalı alanda çalışır. Ayrıca, işlemin diğer sitelerden belirli türde hassas veriler almasını engeller. Sonuç olarak, site izolasyonu sayesinde kötü amaçlı bir web sitesinin diğer sitelerden veri çalmak için Spectre gibi spekülatif yan kanal saldırılarını kullanması çok daha zordur. Chrome ekibi ek yaptırımları tamamladıkça Site İzolasyon özelliği, saldırganın sayfası kendi işleminde bazı kuralları ihlal edebilse bile yardımcı olacaktır.
Site izolasyonu, güvenilmeyen web sitelerinin diğer web sitelerindeki hesaplarınızdan bilgi erişmesini veya bu bilgileri çalmasını etkili bir şekilde zorlaştırır. Yakın zamandaki Meltdown ve Spectre yan kanal saldırıları gibi çeşitli güvenlik hatası türlerine karşı ek koruma sağlar.
Site izolasyonu hakkında daha fazla bilgi için Google Güvenlik blogundaki makalemizi inceleyin.
Kaynaklar Arası Okuma Engelleme
Tüm siteler arası sayfalar ayrı işlemlere yerleştirilmiş olsa bile sayfalar, resim ve JavaScript gibi bazı siteler arası alt kaynakları meşru bir şekilde isteyebilir. Kötü amaçlı bir web sayfası, banka bakiyeniz gibi hassas veriler içeren bir JSON dosyası yüklemek için <img>
öğesini kullanabilir:
<img src="https://your-bank.example/balance.json" />
<!-- Note: the attacker refused to add an `alt` attribute, for extra evil points. -->
Site yalıtımı olmadan JSON dosyasının içeriği, oluşturma işleminin belleğine ulaşır. Bu noktada oluşturma işlemi, geçerli bir resim biçimi olmadığını fark eder ve resim oluşturmaz. Ancak saldırgan, bu bellek parçasını okumak için Spectre gibi bir güvenlik açığından yararlanabilir.
Saldırgan, hassas verileri belleğe kaydetmek için <img>
yerine <script>
kullanabilir:
<script src="https://your-bank.example/balance.json"></script>
Cross-Origin Read Blocking (CORB), balance.json
içeriğinin MIME türüne göre oluşturma işlemi belleğine girmesini engelleyen yeni bir güvenlik özelliğidir.
CORB'nin işleyiş şeklini inceleyelim. Bir web sitesi, sunucudan iki tür kaynak isteyebilir:
- HTML, XML veya JSON dokümanları gibi veri kaynakları
- Resim, JavaScript, CSS veya yazı tipleri gibi medya kaynakları
Bir web sitesi, kendi kaynağından veya Access-Control-Allow-Origin: *
gibi izin verici CORS başlıklarıyla diğer kaynaklardan veri kaynakları alabilir. Öte yandan, medya kaynakları izin verilen CORS başlıkları olmadan bile herhangi bir kaynaktan dahil edilebilir.
CORB, aşağıdaki durumlarda oluşturucu işleminin kaynaklar arası veri kaynağı (ör. HTML, XML veya JSON) almasını engeller:
- Kaynakta
X-Content-Type-Options: nosniff
üstbilgisi var - CORS, kaynağa erişime açıkça izin vermiyor
Kaynaklar arası veri kaynağında X-Content-Type-Options: nosniff
üstbilgisi ayarlanmamışsa CORB, HTML, XML veya JSON olup olmadığını belirlemek için yanıt gövdesini koklamaya çalışır. Bazı web sunucuları yanlış yapılandırıldığı ve resimleri örneğin text/html
olarak yayınladığı için bu gereklidir.
İstek arka planda gerçekleştirilse de CORB politikası tarafından engellenen veri kaynakları sürece boş olarak sunulur. Sonuç olarak, kötü amaçlı bir web sayfası, siteler arası verileri çalmak üzere işleme almakta zorlanır.
Optimum güvenlik için ve CORB'den yararlanmak üzere aşağıdakileri yapmanızı öneririz:
- Yanıtları doğru
Content-Type
üstbilgisiyle işaretleyin. (Örneğin, HTML kaynaklarıtext/html
olarak, JSON kaynakları JSON MIME türü ile ve XML kaynakları XML MIME türü ile 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 analiz, JavaScript dosyaları gibi öğelerin engellenmesini önlemek için yanıtlara izin verme yönünde hata yaptığından, doğru şeyi kendiniz doğrulamak daha iyidir.
Daha fazla bilgi için web geliştiricileri için CORB makalesine veya CORB hakkındaki ayrıntılı açıklamamıza göz atın.
Web geliştiricileri site izolasyonunu neden önemsemelidir?
Site izolasyonu, çoğu zaman web geliştiricilerine doğrudan gösterilmeyen, perde arkasında çalışan bir tarayıcı özelliğidir. Örneğin, öğrenilecek yeni bir web'e açık API yoktur. Genel olarak, web sayfaları Site İzolasyonu ile veya Site İzolasyonu olmadan çalıştırıldığında fark edemez.
Ancak bu kuralın bazı istisnaları vardır. Site izolasyonunu etkinleştirmek, web sitenizi etkileyebilecek birkaç belirsiz yan etkiyle birlikte gelir. Bilinen Site İzolasyon sorunlarının bir listesini tutuyoruz ve en önemlilerini aşağıda ayrıntılı olarak açıklıyoruz.
Tam sayfa düzeni artık senkronize değil
Site izolasyonu ile bir sayfanın çerçeveleri artık birden fazla işleme yayılabileceğinden, tam sayfa düzeninin eşzamanlı olması artık garanti edilmez. Bu durum, sayfadaki tüm çerçevelere hemen yayılacağını varsaydığı bir sayfa düzeni değişikliğini etkiler.
Örneğin, social-widget.example
adresinde 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>
Başlangıçta sosyal widget'ın <iframe>
genişliği 123
pikseldir. Ancak FluffyKittens sayfası, genişliği 456
piksele değiştirir (düzenlemeyi tetikler) ve sosyal widget'a aşağıdaki kodu içeren bir mesaj gönderir:
<!-- https://social-widget.example/ -->
<script>
self.onmessage = () => {
console.log(document.documentElement.clientWidth);
};
</script>
Sosyal widget, postMessage
API aracılığıyla 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'nu etkinleştirmeden önce yanıt 456
idi. document.documentElement.clientWidth
öğesine erişmek, Chrome'un Site İzolasyonu'nu etkinleştirmeden önce senkronize olan düzeni zorlar. Ancak Site İzolasyonu etkinleştirildiğinde, çapraz kaynaklı sosyal widget'ın yeniden düzenlenmesi artık ayrı bir işlemde eşzamansız olarak gerçekleşir. Dolayısıyla, yanıt artık 123
(eski width
değeri) olabilir.
Bir sayfa, kaynaktan bağımsız <iframe>
öğesinin boyutunu değiştirip ona bir postMessage
gönderirse Site İzolasyonu'nda alıcı çerçeve, mesajı alırken henüz yeni boyutunu bilmiyor olabilir. Daha genel olarak, bir düzen değişikliğinin sayfadaki tüm çerçevelere hemen yayıldığını varsayan sayfalar bu durumda bozulabilir.
Bu örnekte, daha etkili bir çözüm üst çerçevede width
değerini ayarlar ve bir resize
etkinliğini dinleyerek <iframe>
öğesindeki bu değişikliği algılar.
Yükleme işleyicileri daha sık zaman aşımı yaşayabilir
Bir çerçeve gezinirken veya kapatıldığında, hem eski doküman hem de içine yerleştirilmiş tüm alt çerçeve dokümanları unload
işleyicisini çalıştırır. Yeni gezinme aynı oluşturucu işleminde (ör. aynı kaynaktan gezinme için) gerçekleşiyorsa eski dokümanın 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 izolasyonu olmasa bile bazı ana çerçeve gezinmeleri işlemler arasıdır ve bu durum, kaldırma işleyici davranışını etkiler. Örneğin, adres çubuğuna URL'yi yazarak old.example
adresinden new.example
adresine giderseniz new.example
adresine gitme işlemi yeni bir işlemde gerçekleşir. old.example
ve alt çerçevelerinin boşaltma işleyicileri, new.example
sayfası gösterildikten sonra arka planda old.example
işleminde çalışır ve belirli bir zaman aşımı içinde tamamlanmazlarsa eski boşaltma işleyicileri sonlandırılır. Kaldırma işleyicileri zaman aşımından önce bitmeyebileceği için kaldırma davranışı daha az güvenilirdir.
Site izolasyonu sayesinde, siteler arası tüm gezinmeler işlemler arası hale gelir. Böylece farklı sitelerdeki dokümanlar birbirleriyle işlem paylaşmaz. Sonuç olarak, yukarıdaki durum daha fazla durumda geçerli olur ve <iframe>
'lerdeki boşaltma işleyicileri genellikle yukarıda açıklanan arka plan ve zaman aşımı davranışlarına sahiptir.
Site izolasyonundan kaynaklanan bir diğer fark da, boşaltma işleyicilerinin yeni paralel sıralamasıdır: Site izolasyonu olmadan boşaltma işleyicileri, çerçeveler arasında katı bir yukarıdan aşağıya sırayla çalışır. Ancak Site İzolasyonu 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, mümkün olduğunda yaygın kullanım alanları için boşaltma işleyicilerinin güvenilirliğini iyileştirmek üzere çalışıyor. Alt çerçeveyi boşaltma işleyicilerinin henüz belirli özellikleri kullanamadığı hatalardan da haberdarız ve bu sorunları çözmek için çalışıyoruz.
Kaldırma işleyicileri için önemli bir durum, oturum sonu ping'leri göndermektir. Bu işlem genellikle aşağıdaki şekilde yapılır:
addEventListener('pagehide', () => {
const image = new Image();
img.src = '/end-of-session';
});
Bu değişiklik doğrultusunda daha etkili bir yaklaşım, onun yerine navigator.sendBeacon
kullanmaktır:
addEventListener('pagehide', () => {
navigator.sendBeacon('/end-of-session');
});
İstek üzerinde daha fazla kontrole ihtiyacınız varsa Getirme API'sinin keepalive
seçeneğini kullanabilirsiniz:
addEventListener('pagehide', () => {
fetch('/end-of-session', {keepalive: true});
});
Sonuç
Site izolasyonu, her siteyi kendi işleminde izole ederek güvenilmeyen web sitelerinin diğer web sitelerindeki hesaplarınıza erişmesini veya bu hesaplardaki bilgileri çalmasını zorlaştırır. Bu kapsamda CORB, hassas veri kaynaklarını oluşturma işleminden uzak 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ü okuyup geri bildirimde bulunan Alex Moshchuk, Charlie Reis, Jason Miller, Nasko Oskov, Philip Walton, Shubhi Panicker ve Thomas Steiner'e teşekkür ederiz.