CSRF, XSSI ve kaynaklar arası bilgi sızıntılarını önleyin.
Web kaynaklarınızı neden izole etmeniz gerekir?
Birçok web uygulaması, siteler arası istek sahtekarlığı (CSRF), siteler arası komut dosyası dahil etme (XSSI), zamanlama saldırıları, kaynaklar arası bilgi sızıntıları veya kurgusal yürütme yan kanal (Spectre) saldırıları gibi kaynaklar arası saldırılara karşı savunmasızdır.
Get Metadata (Meta Verileri Getir) istek üstbilgileri, uygulamanızı bu yaygın çapraz kaynak saldırılarına karşı korumak için güçlü bir derinlemesine savunma mekanizması (Kaynak İzolasyonu 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üklenmemesi yaygın bir durumdur. Bu tür durumlarda, Meta Veri Getirme istek başlıklarına dayanan bir Kaynak İzolasyonu 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 istek üstbilgileri, tüm modern tarayıcı motorlarında desteklenir.
Arka plan
Web varsayılan olarak açık olduğundan ve uygulama sunucunuz dış uygulamalardan kaynaklanan iletişimlere karşı kendini kolayca koruyamadığından birçok site arası saldırı mümkündür. Tipik bir çapraz kaynak saldırısı, siteler arası istek sahtekarlığıdır (CSRF). Bir saldırgan, kullanıcıyı kontrol ettiği bir siteye kandırır ve ardından kullanıcının giriş yaptığı sunucuya bir form gönderir. Sunucu, isteğin başka bir alan adından (siteler arası) kaynaklanıp kaynaklanmadığını anlayamadığından ve tarayıcı siteler arası isteklere otomatik olarak çerez eklediğinden, saldırgan tarafından kullanıcı adına talep edilen eylemi yürütür.
Siteler arası komut dosyası ekleme (XSSI) veya kaynaklar arası bilgi sızıntıları gibi diğer siteler arası saldırılar, CSRF'ye benzer ve bu saldırılar, saldırgan tarafından kontrol edilen bir belgede mağdur uygulamasından gelen kaynakların yüklenmesini ve mağdur uygulamaları hakkındaki bilgilerin sızdırılmasını temel alır. Uygulamalar güvenilir istekleri güvenilir olmayanlardan kolayca ayırt edemediği için kötü amaçlı siteler arası trafiği atamaz.
Meta Verileri Getirme ile Tanışın
Meta Verileri Getirme istek üstbilgileri, sunucuların kaynaklar arası saldırılara karşı kendilerini korumasına yardımcı olmak üzere tasarlanmış yeni bir web platformu güvenlik özelliğidir. Bir dizi Sec-Fetch-*
üst bilgisinde 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, geliştiricilerin bir isteği yapılma şekline ve kullanılacağı bağlama göre kabul etme veya reddetme kararını vermelerine olanak tanıyarak yalnızca kendi uygulamaları tarafından gönderilen meşru isteklere yanıt vermelerine olanak tanır.
![JavaScript'teki 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.](https://web.developers.google.cn/static/articles/fetch-metadata/image/a-fetch-request-https-c7b9ae23ad7f.png?authuser=9&hl=tr)
Sec-Fetch-*
üstbilgileri tarafından sağlanan HTTP isteğindeki ek bağlam nedeniyle sunucu tarafından reddedilebilir.
![https://evil.example adresinde bir img öğesinin src özelliğini "https://site.example/foo.json" olarak ayarlayan resim, tarayıcının "Sec-Fetch-Site: cross-site" HTTP istek başlığını göndermesine neden olur.](https://web.developers.google.cn/static/articles/fetch-metadata/image/an-image-httpsevilex-f0db21158caeb.png?authuser=9&hl=tr)
Sec-Fetch-Site
Sec-Fetch-Site
, sunucuya isteği hangi sitenin gönderdiğini bildirir. Tarayıcı bu değeri aşağıdakilerden birine ayarlar:
- İstek kendi uygulamanız (ör.
site.example
) tarafından yapıldıysasame-origin
- İstek, sitenizin bir alt alanı (ör.
bar.site.example
) tarafından yapıldıysasame-site
- İstek açıkça kullanıcının kullanıcı aracısıyla etkileşiminden (ör. yer işaretini tıklama) kaynaklanıyorsa
none
- İstek başka bir web sitesi (ör.
evil.example
) tarafından gönderildiysecross-site
Sec-Fetch-Mode
Sec-Fetch-Mode
, isteğin modunu belirtir. Bu, yaklaşık olarak 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 gezinme isteğini belirtirken no-cors
, resim yükleme gibi kaynak isteklerini belirtir.
Sec-Fetch-Dest
Sec-Fetch-Dest
, 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 üst bilgilerinin sağladığı ek bilgiler oldukça basittir. Ancak ek bağlam, yalnızca birkaç satır kodla sunucu tarafında güçlü bir güvenlik mantığı (Kaynak İzolasyonu Politikası olarak da bilinir) oluşturmanıza olanak tanır.
Kaynak İzolasyonu Politikası Uygulama
Kaynak İzolasyonu Politikası, kaynaklarınızın harici web siteleri tarafından istenmesini engeller. Bu tür trafiği engellemek 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 isteklerine ve 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 bırakılabilir.
1. Adım: Getirme Meta Verilerini göndermeyen tarayıcılardan gelen isteklere izin verin
Tüm tarayıcılar Meta Verileri Getir özelliğini desteklemediğinden, sec-fetch-site
olup olmadığını kontrol ederek Sec-Fetch-*
üst bilgilerini 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. Bunlar özellikle aşağıdakilerle ilgili taleplerdir:
- Kendi uygulamanızdan başlıyor (ör.
site.example
tarafından yapılansite.example/foo.json
isteklerine her zaman izin verileceği aynı kaynak isteği). - Kaynağı alt alanlarınızdan gelir.
- Açık bir şekilde kullanıcının, kullanıcı aracısıyla etkileşiminden (ör. doğrudan gezinme veya bir yer işaretini tıklayarak vb.) kaynaklanan.
if req['sec-fetch-site'] in ('same-origin', 'same-site', 'none'):
return True # Allow this request
3. Adım: Basit üst düzey gezinmeye ve iç çerçeve oluşturmaya izin verin
Diğer sitelerden sitenize bağlanmaya devam edebilmesi 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 sunması amaçlanan uç noktaları devre dışı bırakın (İsteğe bağlı)
Bazı durumlarda, uygulamanız siteler arası yüklenmesi gereken kaynaklar sağlayabilir. Bu kaynakların yol veya uç nokta bazında muaf tutulması gerekir. Bu tür uç nokta örnekleri:
- Kaynaklar arası erişilmesi amaçlanan uç noktalar: Uygulamanız,
CORS
etkinleştirilmiş uç noktalar sunuyorsa bu uç noktalara siteler arası isteklerin hâlâ mümkün olmasını sağlamak için bunları kaynak izolasyonunun dışında bırakmanız gerekir. - Herkese açık kaynaklar (ör. görüntüler, stiller vb.): Diğer sitelerden gelen çapraz kaynak olarak yüklenebilir olması 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ı ve gezinmeyle ilgili olmayan diğer tüm istekleri reddedin
Diğer tüm siteler arası istekler, bu Kaynak İzolasyonu Politikası tarafından reddedilerek 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 sağlam bir Kaynak Yalıtım Politikası'nın eksiksiz bir şekilde uygulandığı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 İzolasyonu Politikası Dağıtma
- Sitenizin nasıl davrandığını günlüğe kaydedip izlemek ve kısıtlamaların geçerli trafiği etkilemediğinden emin olmak için yukarıdaki kod snippet'i gibi bir modül yükleyin.
- Geçerli çapraz kaynak uç noktalarını hariç tutarak olası ihlalleri düzeltin.
- Uyumlu olmayan istekleri çıkararak politikayı uygulayın.
Politika ihlallerini belirleme ve düzeltme
İlk önce sunucu tarafı kodunuzda raporlama modunda etkinleştirerek politikanızı yan etki içermeyen bir şekilde test etmeniz önerilir. Alternatif olarak, bu mantığı ara katman yazılımında veya üretim trafiğine uygulandığında politikanızın oluşturabileceği ihlalleri günlüğe kaydeden ters proxy'de de uygulayabilirsiniz.
Google'da Meta Veri Getirme Kaynak Yalıtımı Politikası'nı kullanıma sunma deneyimimize göre çoğu uygulama varsayılan olarak bu tür bir politikayla uyumludur ve siteler arası trafiğe izin vermek için uç noktaların hariç tutulmasını nadiren gerektirir.
Kaynak İzolasyonu Politikası Uygulama
Politikanızın geçerli üretim trafiğini etkilemediğini kontrol ettikten sonra, kısıtlamaları uygulamaya ve diğer sitelerin kaynaklarınızı isteyemeyeceği konusunda garanti vermeye ve kullanıcılarınızı siteler arası saldırılara karşı korumaya hazır olursunuz.
Daha fazla bilgi
- W3C Getirme Meta Veri İsteği Başlıkları spesifikasyonu
- Fetch Metadata Playground (Meta Verileri Getirme Oyun Alanı)
- Google I/O konuşması: Web Uygulamalarını Modern Platform Özellikleriyle Güvenli Hale Getirme (Slaytlar)