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

CSRF, XSSI ve kaynaklar arası bilgi sızıntıları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 açığa çıkan kaynakların yalnızca uygulamanın kendisi tarafından yüklenmesi, başka web siteleri tarafından yüklenmesi sık karşılaşılan bir durumdur. Bu gibi durumlarda, Meta Verileri Getirme isteği başlıklarına dayalı bir Kaynak Yalıtımı Politikası dağıtmak çok az çaba gerektirir ve aynı zamanda uygulamayı siteler arası saldırılara karşı korur.

Tarayıcı uyumluluğu

Meta Verileri Getirme isteği üstbilgileri, tüm modern tarayıcı motorlarında desteklenir.

Tarayıcı Desteği

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

Kaynak

Arka plan

Web'in varsayılan olarak açık olması ve uygulama sunucunuzun harici uygulamalardan gelen iletişimlere karşı kendisini kolayca koruyamadığı için siteler arası birçok saldırıya neden olabilir. 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 kaynaktan farklı 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 atayamaz.

Getirme Meta Verileri ile Tanışın

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. Bir dizi Sec-Fetch-* üstbilgisinde HTTP isteğinin bağlamı hakkında bilgi sağlayarak yanıt veren sunucunun isteği işlemeden önce güvenlik politikaları 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.

Aynı Kaynak
Kendi sunucunuz (aynı kaynak) tarafından sunulan sitelerden gelen istekler çalışmaya devam edecektir. 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.
  • Kenar: 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 (istek kendi uygulamanız tarafından gönderildiyse (ör. site.example))
  • same-site; istek sitenizin bir alt alanı tarafından yapıldıysa (ör. bar.site.example)
  • none (istek, kullanıcının kullanıcı aracısıyla etkileşiminden (ör. yer işaretini tıklama) kaynaklanıyorsa)
  • cross-site, istek başka bir web sitesi tarafından gönderildiyse (ör. evil.example)

Sec-Fetch-Mode

Tarayıcı Desteği

  • Chrome: 76.
  • Kenar: 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 gösterir.

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. 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 Verileri getirme özelliğinin kullanımı

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 Yalıtım Politikası Uygulama

Kaynak Yalıtımı 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 kaynaklar arası bilgi sızıntıları gibi siteler arası yaygın 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ığın kapsamı dışında kalabilir.

1. Adım: Getirme meta verileri göndermeyen tarayıcılardan gelen isteklere izin verin

Tüm tarayıcılar Getirme Meta Verilerini desteklemediğinden, sec-fetch-site olup olmadığını kontrol ederek Sec-Fetch-* üstbilgilerini ayarlamayan isteklere izin vermeniz gerekir.

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

2. Adım: Aynı site ve tarayıcı tarafından başlatılan isteklere izin verin

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

  • Kendi uygulamanızdan oluşturun (ör. site.example tarafından site.example/foo.json isteğinde bulunulduğunda her zaman izin verileceği aynı kaynaklı istek).
  • Alt alan adlarınızdan gelmelidir.
  • Açıkça bir kullanıcının kullanıcı aracısıyla etkileşiminden (ör. doğrudan gezinme veya bir yer işaretini tıklayarak) kaynaklanır.
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
  return True  # Allow this request

3. Adım: Üst düzey gezinme ve iFrame oluşturmaya 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 bazında muaf tutulması gerekir. Bu tür uç noktalara ilişkin örnekler şunlardır:

  • 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 yüklenebilecek çapraz kaynak olması gereken, herkese açık ve kimliği doğrulanmamış tüm 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 tüm diğer istekleri reddedin

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

Örnek: Aşağıdaki kod, basit gezinme isteklerine izin verirken kötü amaçlı olabilecek siteler arası kaynak isteklerini reddetmek için sunucuda veya bir ara yazılım olarak güvenilir bir Kaynak Yalıtım Politikası'nın eksiksiz uygulaması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 Yalıtım 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 çapraz kaynak uç noktalarını hariç tutarak olası ihlalleri düzeltin.
  3. Politikaya uygun olmayan istekleri atarak politikayı uygulayın.

Politika ihlallerini belirleme 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 Yalıtım Politikası'nı zorunlu kılma

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