Meta Verileri Getirme özelliğiyle kaynaklarınızı web saldırılarına karşı koruyun

CSRF, XSSI ve kaynaktan kaynaka bilgi sızıntısını önleyin.

Lukas Weichselbaum
Lukas Weichselbaum

Web kaynaklarınızı neden ayırmalısınız?

Birçok web uygulaması, siteler arası istek sahtekarlığı (CSRF), siteler arası komut dosyası ekleme (XSSI), zamanlama saldırıları, kaynak arası bilgi sızıntısı veya spekülatif yürütme yan kanalı (Spectre) saldırıları gibi kaynak arası saldırılara karşı savunmasızdır.

Meta Veri Getir istek üstbilgileri, uygulamanızı bu yaygın kaynaktan kaynaka saldırılara karşı korumak için güçlü bir ayrıntılı savunma mekanizması (Kaynak İzolasyon Politikası) dağıtmanıza olanak tanır.

Belirli bir web uygulaması tarafından sunulan kaynakların diğer web siteleri tarafından değil, yalnızca uygulamanın kendisi tarafından yüklenmesi yaygın bir durumdur. Bu gibi durumlarda, Meta Veri Getirme istek üstbilgilerine dayalı bir Kaynak İzolasyon Politikası dağıtmak çok az çaba gerektirir ve aynı zamanda uygulamayı siteler arası saldırılara karşı korur.

Tarayıcı uyumluluğu

Meta Veri Getir istek başlıkları tüm modern tarayıcı motorlarında desteklenir.

Tarayıcı desteği

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Kaynak

Arka plan

Web varsayılan olarak açık olduğundan ve uygulama sunucunuz kendisini harici uygulamalardan gelen iletişime karşı kolayca koruyamadığından siteler arası birçok saldırı mümkündür. Kötü amaçlı bir kullanıcının kullanıcıyı kontrol ettiği bir siteye çektiği ve ardından kullanıcının giriş yaptığı sunucuya bir form gönderdiği siteler arası istek sahtekarlığı (CSRF), tipik bir kaynakta çapraz saldırıdır. Sunucu, isteğin başka bir alandan (siteler arası) gelip gelmediğini belirleyemediğinden ve tarayıcı, siteler arası isteklere otomatik olarak çerez eklediğinden, sunucu saldırgan tarafından istenen işlemi kullanıcı adına yürütür.

Siteler arası komut dosyası dahil etme (XSSI) veya kaynak arası bilgi sızıntısı gibi diğer siteler arası saldırılar, CSRF'ye benzer niteliktedir ve kurban uygulamasından saldırgan tarafından kontrol edilen bir belgeye kaynak yüklemeye ve kurban uygulamalarıyla ilgili bilgileri sızdırmaya dayanır. Uygulamalar, güvenilir istekleri güvenilmeyen isteklerden kolayca ayırt edemedikleri için siteler arası zararlı trafiği reddedemez.

Meta Verileri Getirme özelliğini kullanıma sunuyoruz

Meta Veri Getir istek üstbilgileri, sunucuların kaynaktan kaynakta saldırılara karşı kendilerini korumalarına yardımcı olmak için tasarlanmış yeni bir web platformu güvenlik özelliğidir. Sec-Fetch-* başlıkları, bir HTTP isteğinin bağlamı hakkında bilgi sağlayarak yanıt veren sunucunun isteği işlemeden önce güvenlik politikalarını uygulamasına olanak tanır. Bu sayede geliştiriciler, isteklerin gönderilme şekline ve kullanılacağı bağlama göre isteklerini kabul edip etmeyeceklerine karar verebilir. Böylece yalnızca kendi uygulamaları tarafından gönderilen meşru isteklere yanıt verebilirler.

Same-Origin
Kendi sunucunuz tarafından sunulan sitelerden gelen istekler (aynı kaynak) çalışmaya devam eder. JavaScript'te https://site.example/foo.json kaynağı için https://site.example adresinden gelen bir getirme isteği, tarayıcının "Sec Fetch-Site: same-origin" HTTP istek başlığını göndermesine neden olur.
Siteler arası
Sec-Fetch-* üst bilgileri tarafından sağlanan HTTP isteğinde ek bağlam bulunduğundan, siteler arası kötü amaçlı istekler sunucu tarafından reddedilebilir. https://evil.example adresindeki bir img öğesinin src özelliğini "https://site.example/foo.json" olarak ayarlayan bir resim, tarayıcının "Sec-Fetch-Site: cross-site" HTTP istek üstbilgisini göndermesine neden olur.

Sec-Fetch-Site

Tarayıcı desteği

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Kaynak

Sec-Fetch-Site, sunucuya isteği hangi sitenin gönderdiğini bildirir. Tarayıcı bu değeri aşağıdakilerden birine ayarlar:

  • same-origin (isteğiniz kendi uygulamanız tarafından gönderildiyse (ör. site.example))
  • İstek sitenizin bir alt alan adı tarafından gönderildiyse (ör. bar.site.example) same-site
  • none (istek, kullanıcının kullanıcı aracısıyla etkileşiminden (ör. yer işaretini tıklama) kaynaklanıyorsa)
  • İstek başka bir web sitesi tarafından gönderildiyse (ör. evil.example) cross-site

Sec-Fetch-Mode

Tarayıcı desteği

  • Chrome: 76.
  • Edge: 79.
  • Firefox: 90.
  • Safari: 16.4.

Kaynak

Sec-Fetch-Mode, isteğin modunu gösterir. Bu, kabaca isteğin türüne karşılık gelir ve kaynak yüklemelerini gezinme isteklerinden ayırt etmenize olanak tanır. Örneğin, navigate hedefi üst düzey bir gezinme isteğini, no-cors ise resim yükleme gibi kaynak isteklerini belirtir.

Sec-Fetch-Dest

Tarayıcı desteği

  • Chrome: 80.
  • Edge: 80.
  • Firefox: 90.
  • Safari: 16.4.

Kaynak

Sec-Fetch-Dest, bir isteğin hedefini gösterir (ör. bir script veya img etiketi, tarayıcı tarafından bir kaynağın istenmesine neden olduysa).

Kaynaklar arası saldırılara karşı koruma sağlamak için Meta Veri Getirme'yi kullanma

Bu istek başlıklarının sağladığı ek bilgiler oldukça basittir ancak ek bağlam, sunucu tarafında yalnızca birkaç kod satırı kullanarak Kaynak İzolasyon Politikası olarak da bilinen güçlü bir güvenlik mantığı oluşturmanıza olanak tanır.

Kaynak İzolasyonu Politikası'nı uygulama

Kaynak İzolasyon Politikası, kaynaklarınızın harici web siteleri tarafından istenmesini engeller. Bu tür trafiğin engellenmesi, CSRF, XSSI, zamanlama saldırıları ve kaynak arası bilgi sızıntısı gibi yaygın siteler arası web güvenlik açıklarını azaltır. Bu politika, uygulamanızın tüm uç noktaları için etkinleştirilebilir ve kendi uygulamanızdan gelen tüm kaynak isteklerinin yanı sıra doğrudan gezinmelere (HTTP GET isteği aracılığıyla) izin verir. Siteler arası bağlamda yüklenmesi gereken uç noktalar (ör. CORS kullanılarak yüklenen uç noktalar) bu mantıktan hariç tutulabilir.

1. adım: Meta Veri Getirme isteği göndermeyen tarayıcılardan gelen isteklere izin verin

Meta Veri Getirme özelliği tüm tarayıcılar tarafından desteklenmediğinden, sec-fetch-site varlığı kontrol edilerek Sec-Fetch-* üstbilgilerinin ayarlanmadığı isteklere izin vermeniz gerekir.

if not req['sec-fetch-site']:
  return True  # Allow this request

2. Adım: Aynı siteden ve tarayıcıdan başlatılan isteklere izin verin

Kökler arası bir bağlamda (evil.example gibi) kaynaklanmayan tüm isteklere izin verilir. Özellikle aşağıdakiler için istekte bulunabilirsiniz:

  • Kendi uygulamanızdan gelmelidir (ör. site.example'in site.example/foo.json isteklerine her zaman izin verilecek bir aynı kaynak isteği).
  • Alt alan adlarınızdan gelmelidir.
  • Kullanıcının kullanıcı aracısıyla etkileşiminden (ör. doğrudan gezinme veya yer işaretini tıklama) açıkça kaynaklanır.
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
  return True  # Allow this request

3. adım: Basit üst düzey gezinme ve iframing'e izin verin

Sitenizin diğer sitelerden bağlantı alabilmesi için basit (HTTP GET) üst düzey gezinmeye izin vermeniz gerekir.

if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
  # <object> and <embed> send navigation requests, which we disallow.
  and req['sec-fetch-dest'] not in ('object', 'embed'):
    return True  # Allow this request

4. Adım: Siteler arası trafik yayınlamak için tasarlanmış uç noktaları devre dışı bırakma (isteğe bağlı)

Bazı durumlarda, uygulamanız siteler arası yüklenmesi amaçlanan kaynaklar sağlayabilir. Bu kaynakların yol veya uç nokta başına muaf tutulması gerekir. Bu tür uç noktalara örnek olarak şunlar verilebilir:

  • Kaynaklar arası erişime yönelik uç noktalar: Uygulamanız CORS etkin uç noktalar sunuyorsa bu uç noktalara siteler arası isteklerin yine mümkün olmasını sağlamak için bunları kaynak izolasyonundan açıkça hariç tutmanız gerekir.
  • Herkese açık kaynaklar (ör. resimler, stiller vb.): Diğer sitelerden kaynaktan bağımsız olarak yüklenmesi gereken herkese açık ve kimliği doğrulanmamış kaynaklar da muaf tutulabilir.
if req.path in ('/my_CORS_endpoint', '/favicon.png'):
  return True

5. Adım: Siteler arası olan ve gezinme amaçlı olmayan diğer tüm istekleri reddedin

Diğer tüm siteler arası istekler bu Kaynak İzolasyon Politikası tarafından reddedilir ve böylece uygulamanız yaygın siteler arası saldırılara karşı korunur.

Örnek: Aşağıdaki kod, basit gezinme isteklerine izin verirken siteler arası kötü amaçlı olabilecek kaynak isteklerini reddetmek için sunucu üzerinde veya bir arabirim olarak güçlü bir Kaynak İzolasyon Politikası'nın tam olarak uygulanmasını göstermektedir:

# Reject cross-origin requests to protect from CSRF, XSSI, and other bugs
def allow_request(req):
  # Allow requests from browsers which don't send Fetch Metadata
  if not req['sec-fetch-site']:
    return True

  # Allow same-site and browser-initiated requests
  if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
    return True

  # Allow simple top-level navigations except <object> and <embed>
  if req['sec-fetch-mode'] == 'navigate' and req.method == 'GET'
    and req['sec-fetch-dest'] not in ('object', 'embed'):
      return True

  # [OPTIONAL] Exempt paths/endpoints meant to be served cross-origin.
  if req.path in ('/my_CORS_endpoint', '/favicon.png'):
    return True

  # Reject all other requests that are cross-site and not navigational
  return False

Kaynak İzolasyon Politikası dağıtma

  1. Sitenizin nasıl davrandığını günlüğe kaydetmek ve izlemek ve kısıtlamaların meşru trafiği etkilemediğinden emin olmak için yukarıdaki kod snippet'i gibi bir modül yükleyin.
  2. Geçerli kaynak dışı uç noktaları muaf tutarak olası ihlalleri düzeltin.
  3. Politikaya uygun olmayan istekleri atarak politikayı uygulayın.

Politika ihlallerini tespit etme ve düzeltme

Politikanızı önce sunucu tarafı kodunuzda raporlama modunda etkinleştirerek yan etki olmadan test etmeniz önerilir. Alternatif olarak bu mantığı orta katmana veya üretim trafiğine uygulandığında politikanızın oluşturabileceği tüm ihlalleri günlüğe kaydeden bir ters proxy'ye de uygulayabilirsiniz.

Google'da Getir Meta Verileri Kaynak İzolasyon Politikası'nı kullanıma sunma deneyimimizden yola çıkarak, çoğu uygulamanın varsayılan olarak bu tür bir politikayla uyumlu olduğunu ve siteler arası trafiğe izin vermek için uç noktaların nadiren muaf tutulması gerektiğini söyleyebiliriz.

Kaynak İzolasyonu Politikası'nı uygulama

Politikanızın meşru üretim trafiğini etkilemediğini kontrol ettikten sonra, diğer sitelerin kaynaklarınızı isteyemeyeceğinden emin olarak ve kullanıcılarınızı siteler arası saldırılara karşı koruyarak kısıtlamaları uygulamaya hazırsınız demektir.

Daha fazla bilgi