Kullanıcı verilerini modern web uygulamalarında güvenli bir şekilde barındırma

David Dworken
David Dworken

Birçok web uygulamasının kullanıcı tarafından kontrol edilen içerik göstermesi gerekir. Bu, kullanıcı tarafından yüklenen resimleri (ör. profil fotoğrafları) yayınlamak kadar basit veya kullanıcı tarafından kontrol edilen HTML'yi oluşturmak (ör. web geliştirme eğitimi) kadar karmaşık olabilir. Bu işlemin güvenli bir şekilde yapılması her zaman zor olmuştur. Bu nedenle, çoğu web uygulaması türüne uygulanabilecek kolay ancak güvenli çözümler bulmak için çalıştık.

Güvenilmeyen içeriği izole etmek için klasik çözümler

Kullanıcı tarafından kontrol edilen içeriği güvenli bir şekilde yayınlamanın klasik çözümü, korumalı alan adları olarak bilinenleri kullanmaktır. Temel fikir, uygulamanızın ana alanı example.com ise güvenilmeyen tüm içerikleri exampleusercontent.com üzerinde yayınlayabilmenizdir. Bu iki alan siteler arası olduğundan exampleusercontent.com'deki kötü amaçlı içerikler example.com'ı etkileyemez.
Bu yaklaşım, resimler, indirmeler ve HTML dahil olmak üzere güvenilmeyen her türlü içeriği güvenli bir şekilde sunmak için kullanılabilir. Bu özelliği resimler veya indirmeler için kullanmanız gerekmese de özellikle eski tarayıcılarda içerik kokulaması risklerini önlemeye yardımcı olur.
Sandbox alanları sektörde yaygın olarak kullanılır ve uzun süredir iyi sonuçlar vermektedir. Ancak bu tür reklamların iki önemli dezavantajı vardır:

  • Uygulamaların genellikle içerik erişimini tek bir kullanıcıyla kısıtlaması gerekir. Bu da kimlik doğrulama ve yetkilendirmenin uygulanmasını gerektirir. Korumalı alan adları, çerezleri ana uygulama alanıyla kasıtlı olarak paylaşmadığından bu işlemin güvenli bir şekilde yapılması çok zordur. Kimlik doğrulamayı desteklemek için sitelerin yetenek URL'lerini kullanması veya korumalı alan adı için ayrı kimlik doğrulama çerezleri ayarlaması gerekir. Bu ikinci yöntem, özellikle birçok tarayıcının siteler arası çerezleri varsayılan olarak kısıtladığı modern web'de sorunludur.
  • Kullanıcı içeriği ana siteden izole edilir ancak diğer kullanıcı içeriklerinden izole edilmez. Bu durum, kötü amaçlı kullanıcı içeriğinin korumalı alan alan adındaki diğer verilere saldırma riskini (örneğin, aynı kaynaktan verileri okuyarak) oluşturur.

Ayrıca, kaynaklar izole bir alanda net bir şekilde segmentlere ayrıldığı için korumalı alan adlarının kimlik avı risklerini azaltmaya yardımcı olduğunu da belirtmek gerekir.

Kullanıcı içeriği yayınlamak için modern çözümler

Web zaman içinde gelişti ve artık güvenilmeyen içerikleri yayınlamanın daha kolay ve daha güvenli yolları var. Bu konuda birçok farklı yaklaşım vardır. Bu nedenle, şu anda Google'da yaygın olarak kullanılan iki çözümü özetleyeceğiz.

1. Yaklaşım: Etkin olmayan kullanıcı içeriklerini yayınlama

Bir sitenin yalnızca etkin olmayan kullanıcı içeriği (ör. resimler ve indirmeler gibi HTML veya JavaScript olmayan içerikler) yayınlaması gerekiyorsa bu işlem artık izole bir korumalı alan adı olmadan güvenli bir şekilde yapılabilir. İki önemli adım vardır:

  • Content-Type üst bilgisini her zaman tüm tarayıcılar tarafından desteklenen ve etkin içerik içermediği garanti edilen iyi bilinen bir MIME türüne ayarlayın (şüphe duyuyorsanız application/octet-stream güvenli bir seçimdir).
  • Ayrıca, tarayıcının yanıtı tamamen izole etmesini sağlamak için her zaman aşağıdaki yanıt üstbilgilerini ayarlayın.
Yanıt Üstbilgisi Purpose

X-Content-Type-Options: nosniff

İçerik kokulamaya karşı koruma sağlar

Content-Disposition: attachment; filename="download"

Oluşturma yerine indirme işlemi tetikler.

Content-Security-Policy: sandbox

İçeriği, ayrı bir alanda yayınlanmış gibi korumalı alana alır.

Content-Security-Policy: default-src ‘none'

JavaScript yürütmeyi (ve alt kaynakların dahil edilmesini) devre dışı bırakır

Cross-Origin-Resource-Policy: same-site

Sayfanın siteler arası dahil edilmesini engeller

Bu başlık kombinasyonu, yanıtın yalnızca uygulamanız tarafından alt kaynak olarak yüklenmesini veya kullanıcı tarafından dosya olarak indirilmesini sağlar. Ayrıca başlıklar, CSP korumalı alan başlığı ve default-src kısıtlaması aracılığıyla tarayıcı hatalarına karşı birden fazla koruma katmanı sağlar. Genel olarak, yukarıda özetlenen kurulum, bu şekilde sunulan yanıtların enjeksiyon veya yalıtım açıklıklarına yol açamayacağı konusunda yüksek düzeyde güven sağlar.

Derinlemesine savunma

Yukarıdaki çözüm, XSS'ye karşı genellikle yeterli bir savunma sağlar. Ancak ek güvenlik katmanları sağlamak için uygulayabileceğiniz birkaç ek güçlendirme önlemi vardır:

  • IE11 ile uyumluluk için bir X-Content-Security-Policy: sandbox başlığı ayarlayın.
  • Uç noktasının yerleştirilmesini engellemek için bir Content-Security-Policy: frame-ancestors 'none' başlığı ayarlayın.
  • Aşağıdakiler tarafından izole alt alan adında korumalı alan kullanıcı içeriği:
    • Kullanıcı içeriğini izole bir alt alan adında yayınlama (ör. Google, product.usercontent.google.com gibi alanlar kullanır).
    • Kaynaklar arası izolasyonu etkinleştirmek için Cross-Origin-Opener-Policy: same-origin ve Cross-Origin-Embedder-Policy: require-corp'yi ayarlayın.

2. Yaklaşım: Etkin kullanıcı içerikleri yayınlama

Etkin içeriklerin (ör. HTML veya SVG resimleri) güvenli bir şekilde sunulması, klasik korumalı alan alan yaklaşımının zayıflıkları olmadan da yapılabilir.
En basit seçenek, tarayıcıya yanıtı izole etmesini söylemek için Content-Security-Policy: sandbox üstbilgisinin kullanılmasıdır. Şu anda tüm web tarayıcıları korumalı alan belgeleri için işlem izolasyonu uygulamasa da tarayıcı işlem modellerinde devam eden iyileştirmeler, korumalı alan içeriğinin yerleştirilmiş uygulamalardan ayrılmasını iyileştirecektir. SpectreJS ve yayınlayıcı güvenliğinin ihlali saldırıları tehdit modelinizin dışındaysa CSP korumalı alanını kullanmak muhtemelen yeterli bir çözümdür.
Google'da, korumalı alan adı kavramını modernleştirerek güvenilmeyen etkin içeriği tamamen izole edebilecek bir çözüm geliştirdik. Temel fikir şudur:

  • Herkese açık son ek listesine eklenen yeni bir korumalı alan adı oluşturun. Örneğin, PSL'ye exampleusercontent.com ekleyerek foo.exampleusercontent.com ve bar.exampleusercontent.com'nin siteler arası olduğundan ve dolayısıyla birbirinden tamamen izole olduğundan emin olabilirsiniz.
  • *.exampleusercontent.com/shim ile eşleşen URL'lerin tümü statik bir shim dosyasına yönlendirilir. Bu ara dosya, message etkinlik işleyicisini dinleyen ve aldığı tüm içeriği oluşturan kısa bir HTML ve JavaScript snippet'i içerir.
  • Ürün bunu kullanmak için $RANDOM_VALUE.exampleusercontent.com/shim için bir iframe veya pop-up oluşturur ve güvenilmeyen içeriği oluşturma işlemi için shim'e göndermek üzere postMessage'ı kullanır.
  • Oluşturulan içerik bir Blob'a dönüştürülür ve korumalı alana alınmış bir iframe içinde oluşturulur.

Bu yaklaşım, klasik korumalı alan yaklaşımına kıyasla tüm içeriğin benzersiz bir sitede tamamen izole edilmesini sağlar. Ayrıca, oluşturulacak verilerin alınmasını ana uygulamanın yapmasıyla, artık özellik URL'lerinin kullanılmasına gerek kalmaz.

Sonuç

Bu iki çözüm birlikte, googleusercontent.com gibi klasik korumalı alan alanlarından üçüncü taraf çerez engellemeyle uyumlu daha güvenli çözümlere geçiş yapmayı mümkün kılar. Google'da, birçok ürünü bu çözümleri kullanacak şekilde taşıdık ve önümüzdeki yıl için daha fazla taşıma işlemi planladık.