tl; dr - İlgili kısımları bulmayı kolaylaştırmak için sonunda bir özet ve cevapta başlıklar vardır. Her şeyi okumak, bunun neden farklı koşullarda nasıl geçerli olduğunu görmeyi kolaylaştırdığını anlamak için yararlı bir arka plan sağladığından tavsiye edilir .
Aynı Menşe Politikası Hakkında
Bu Aynı Menşe Politikasıdır . Tarayıcılar tarafından uygulanan bir güvenlik özelliğidir.
Özel durumunuz, XMLHttpRequest için nasıl uygulandığını gösteriyor (ve getirmeyi kullanırsanız aynı sonuçları alırsınız), ancak diğer şeyler için de geçerlidir (bir üzerine yüklenen görüntüler <canvas>
veya bir'ye yüklenen belgeler gibi <iframe>
), biraz farklı uygulamalar.
(Garip bir şekilde, CSS yazı tipleri için de geçerlidir, ancak bunun nedeni, bulunan dökümhanelerin DRM'de ısrar etmeleridir ve Aynı Köken Politikasının genellikle kapsadığı güvenlik sorunları için değil).
SÇP'ye duyulan ihtiyacı gösteren standart senaryo üç karakterle gösterilebilir :
- Alice, web tarayıcısı olan bir kişidir
- Bob bir web sitesi işletiyor (
https://www.[website].com/
sizin örneğinizde)
- Mallory bir web sitesi işletiyor (
http://localhost:4300
sizin örneğinizde)
Alice, Bob'un sitesinde oturum açtı ve orada bazı gizli veriler var. Belki bir şirket intranetidir (yalnızca LAN'daki tarayıcılar tarafından erişilebilir) veya onun çevrimiçi bankacılığı (yalnızca bir kullanıcı adı ve şifre girdikten sonra aldığınız bir çerezle erişilebilir).
Alice, Alice'in tarayıcısının Bob'un web sitesine (çerezleri ile IP adresinden, vb.) HTTP isteğinde bulunmasına neden olan bazı JavaScript içeren Mallory'nin web sitesini ziyaret eder. Bu, .ppi'yi kullanmak XMLHttpRequest
ve okumak kadar basit olabilir responseText
.
Tarayıcının Aynı Kaynak İlkesi, JavaScript'in Bob'un web sitesi tarafından döndürülen verileri okumasını engeller (Bob ve Alice, Mallory'nin erişmesini istemez). Eğer, örneğin, bir kullanan bir görüntü gösterebilmesi (Not <img>
görüntünün içeriği) JavaScript (veya Mallory maruz kalmadığından dolayı size bu durumda karışımın içine tuval atmak sürece ... kökeni genelinde elemanı olacak bir aynı kökenli oluşturmak ihlal hatası).
Aynı Menşe Politikası, olması gerektiğini düşünmediğinizde neden geçerlidir?
Verilen herhangi bir URL için SÇP'ye ihtiyaç duyulmaması mümkündür. Durumun böyle olduğu birkaç yaygın senaryo şunlardır:
- Alice, Bob ve Mallory aynı kişilerdir.
- Bob tamamen halka açık bilgiler sağlıyor
… Ancak tarayıcının yukarıdakilerden herhangi birinin doğru olup olmadığını bilmesinin bir yolu yoktur, bu nedenle güven otomatik değildir ve SOP uygulanır. Tarayıcının verdiği veriyi farklı bir web sitesine vermesi için izin açıkça verilmelidir.
Aynı Kaynak Politikası neden yalnızca bir web sayfasındaki JavaScript için geçerlidir?
Tarayıcı uzantıları *
, tarayıcı geliştirici araçlarındaki Ağ sekmesi ve Postman gibi uygulamalar yüklü yazılımlardır. Bir web sitesinden, farklı bir web sitesine ait olan JavaScript'e, yalnızca o farklı web sitesini ziyaret ettiğiniz için veri aktarmazlar . Yazılım yüklemek genellikle daha bilinçli bir seçim gerektirir.
Risk olarak kabul edilen üçüncü bir taraf (Mallory) yoktur.
*
Çapraz kaynak sorunlarını önlemek için tarayıcı uzantılarının dikkatli bir şekilde yazılması gerekir. Örneğin Chrome belgelerine bakın .
Sayfadaki verileri JS ile okumadan neden görüntüleyebilirsiniz?
Mallory'nin sitesinin bir tarayıcının üçüncü bir şahıstan veri almasına ve görüntülemesine neden olabileceği birkaç durum vardır (örneğin, <img>
bir görüntüyü görüntülemek için bir öğe ekleyerek ). Mallory'nin JavaScript'in bu kaynaktaki verileri okuması mümkün değildir, ancak yalnızca Alice'in tarayıcısı ve Bob'un sunucusu bunu yapabilir, bu nedenle hala güvenlidir.
CORS
Access-Control-Allow-Origin
HTTP yanıtı başlığı hata mesajı parçasıdır belirtilen CORS Bob açıkça erişim Alice'in tarayıcı üzerinden veri Mallory'nin sitesine izin vermenize olanak sağlar standardı.
Temel bir uygulama şunları içerir:
Access-Control-Allow-Origin: *
… Herhangi bir web sitesinin verileri okumasına izin vermek için yanıt başlıklarında.
Access-Control-Allow-Origin: http://example.com/
… Yalnızca belirli bir sitenin ona erişmesine izin verir ve Bob, birden çok siteye erişmesine izin vermek için Origin
istek başlığına dayalı olarak bunu dinamik olarak oluşturabilir .
Bob'un bu yanıt başlığını nasıl ayarladığına ilişkin ayrıntılar, Bob'un HTTP sunucusuna ve / veya sunucu tarafı programlama diline bağlıdır. Yardımcı olabilecek çeşitli genel yapılandırmalar için bir kılavuz koleksiyonu vardır .
NB: Bazı istekler karmaşıktır ve tarayıcının GET / POST / PUT / JS'nin yapmak istediği her isteği göndermeden önce sunucunun yanıt vermesi gereken bir ön kontrol SEÇENEKLERİ isteği gönderir. Yalnızca Access-Control-Allow-Origin
belirli URL'lere eklenen CORS uygulamaları genellikle bununla tetiklenir.
Açıkçası, CORS aracılığıyla izin vermek, Bob'un yalnızca aşağıdaki durumlarda yapacağı bir şeydir:
- Veriler özel değildi veya
- Mallory güvenildi
Ama ben Bob değilim!
Mallory'nin bu başlığı eklemesi için standart bir mekanizma yoktur, çünkü Bob'un kendi kontrolünde olmadığı web sitesinden gelmesi gerekir.
Bob genel bir API çalıştırıyorsa, CORS'u açmak için bir mekanizma olabilir (belki de isteği belirli bir şekilde biçimlendirerek veya Bob'un sitesi için bir Geliştirici Portalı sitesinde oturum açtıktan sonra bir yapılandırma seçeneği). Bunun Bob tarafından uygulanan bir mekanizma olması gerekecek. Mallory, bir şeyin mevcut olup olmadığını görmek için Bob'un sitesindeki belgeleri okuyabilir veya Bob'la konuşup ondan CORS uygulamasını isteyebilir.
"Ön kontrol için yanıt" dan bahseden hata mesajları
Bazı çapraz kaynak talepleri önceden kontrol edilir .
Bu, (kabaca konuşursak) aşağıdakileri içeren çapraz kaynaklı bir talepte bulunmaya çalıştığınızda gerçekleşir:
- Çerezler gibi kimlik bilgilerini içerir
- Normal bir HTML formuyla oluşturulamaz (örneğin, bir formda kullanamayacağınız özel başlıklar veya bir İçerik Türü vardır
enctype
).
Ön kontrol gerektiren bir şeyi doğru yapıyorsanız
Bu durumlarda daha sonra cevabın kalan hala geçerlidir ama aynı zamanda sunucu olacak (uçuş öncesi isteği için dinleyebilir emin olmak gerekir OPTIONS
(ve GET
, POST
veya sağ ile kendisine gönderme çalışıyor) ve tepki edildi olursa olsun Access-Control-Allow-Origin
başlığı değil, aynı zamanda Access-Control-Allow-Methods
ve Access-Control-Allow-Headers
belirli HTTP yöntemlerine veya başlıklarına izin vermek için.
Yanlışlıkla bir ön kontrolü tetikliyorsanız
Bazen insanlar Ajax isteklerini oluşturmaya çalışırken hatalar yapar ve bazen bunlar ön kontrol ihtiyacını tetikler. API, çapraz kaynaklı isteklere izin verecek şekilde tasarlanmışsa, ancak ön kontrol gerektiren herhangi bir şey gerektirmiyorsa, bu durumda erişimi kesebilir.
Bunu tetikleyen yaygın hatalar şunları içerir:
Access-Control-Allow-Origin
istek üzerine diğer CORS yanıt başlıklarını koymaya çalışıyor . Bunlar isteğe ait değildir, yardımcı hiçbir şey yapmayın (kendinize izin verebileceğiniz bir izin sisteminin amacı nedir?) Ve yalnızca yanıtta görünmelidir.
Content-Type: application/json
içeriğini açıklayacak bir istek gövdesi olmayan bir GET isteğine bir başlık koymaya çalışmak (genellikle yazarın kafasını karıştırdığında Content-Type
ve Accept
).
Her iki durumda da, fazladan istek başlığının kaldırılması genellikle bir ön kontrol ihtiyacını ortadan kaldırmak için yeterli olacaktır (bu, basit istekleri destekleyen ancak önceden kontrol edilmemiş istekleri desteklemeyen API'lerle iletişim kurarken sorunu çözecektir).
Opak tepkiler
Bazen bir HTTP isteğinde bulunmanız gerekir, ancak yanıtı okumanız gerekmez. örneğin, kayıt için sunucuya bir günlük mesajı gönderiyorsanız.
Eğer kullanıyorsanız API (yerine ), o zaman kullanım CORS çalışmayın için yapılandırabilirsiniz.fetch
XMLHttpRequest
Bunun, CORS'un yapmasını istediğiniz herhangi bir şeyi yapmanıza izin vermeyeceğini unutmayın. Yanıtı okuyamayacaksınız. Ön kontrol gerektiren bir talepte bulunamayacaksınız.
Basit bir istekte bulunmanıza, yanıtı görmenize ve Developer Console'u hata mesajlarıyla doldurmanıza izin vermez.
Nasıl yapılacağı, kullanarak bir talepte bulunduğunuzda fetch
ve yanıtı CORS ile görüntüleme izni almadığınızda verilen Chrome hata mesajıyla açıklanmaktadır :
" Kaynak https://example.com/
" konumunda getirme erişimi, https://example.net
CORS politikası tarafından engellendi: Access-Control-Allow-Origin
İstenen kaynakta " " başlığı yok . Opak bir yanıt ihtiyaçlarınızı karşılıyorsa, CORS devre dışıyken kaynağı getirmek için isteğin modunu 'no-cors' olarak ayarlayın.
Böylece:
fetch("http://example.com", { mode: "no-cors" });
CORS Alternatifleri
JSONP
Bob ayrıca, JSONP gibi bir hack kullanarak verileri sağlayabilir; bu, CORS ortaya çıkmadan önce insanların çapraz kökenli Ajax'ı nasıl yaptıklarıdır.
Verileri, Mallory'nin sayfasına enjekte eden bir JavaScript programı biçiminde sunarak çalışır.
Bu, Mallory'nin Bob'a kötü amaçlı kod sağlamayacağına güvenmesini gerektirir.
Ortak temaya dikkat edin: Verileri sağlayan site, tarayıcıya üçüncü taraf bir sitenin tarayıcıya gönderdiği verilere erişmesinin uygun olduğunu bildirmelidir.
JSONP <script>
, verileri sayfada zaten bulunan bir işlevi çağıran bir JavaScript programı biçiminde yüklemek için bir öğe ekleyerek çalıştığından, JSON döndüren bir URL'de JSONP tekniğini kullanmaya çalışmak başarısız olur - genellikle bir CORB hatasıyla - JSON JavaScript değil.
İki kaynağı tek bir kaynağa taşıyın
JS'nin çalıştığı HTML belgesi ve istenen URL aynı kaynakta ise (aynı şemayı, ana bilgisayar adını ve bağlantı noktasını paylaşıyorsa), aynı Kaynak İlkesi varsayılan olarak izin verir. CORS gerekli değildir.
Bir Proxy
Mallory olabilir (o sonra her zamanki gibi HTTP yoluyla Alice'in tarayıcısına onu sunucudan geçebileceği) veri getirmek için sunucu tarafı kodu kullanabilirsiniz.
Ya:
- CORS başlıkları ekle
- yanıtı JSONP'ye dönüştür
- HTML belgesiyle aynı kaynaktan var
Bu sunucu tarafı kodu, üçüncü bir taraf (örneğin CORS Anywhere) tarafından yazılabilir ve barındırılabilir. Bunun gizlilikle ilgili sonuçlarına dikkat edin: Üçüncü taraf, sunucularında kimin neye proxy yaptığını izleyebilir.
Bob'un bunun olması için herhangi bir izin vermesi gerekmiyor.
Bu sadece Mallory ve Bob arasında olduğu için burada güvenlik etkileri yok. Bob'un, Mallory'nin Alice olduğunu düşünmesi ve Mallory'ye Alice ile Bob arasında gizli tutulması gereken verileri sağlamasının bir yolu yoktur.
Sonuç olarak, Mallory bu tekniği yalnızca halka açık verileri okumak için kullanabilir .
Bununla birlikte, başka birinin web sitesinden içerik almanın ve bunu kendi başınıza görüntülemenin telif hakkı ihlali olabileceğini ve sizi yasal işlemlere açabileceğini unutmayın.
Web uygulaması dışında bir şey yazmak
"Neden Aynı Kaynak İlkesi yalnızca bir web sayfasındaki JavaScript için geçerlidir" bölümünde belirtildiği gibi, bir web sayfasına JavaScript yazmayarak SOP'den kaçınabilirsiniz.
Bu, JavaScript ve HTML kullanmaya devam edemeyeceğiniz anlamına gelmez, ancak Node-WebKit veya PhoneGap gibi başka bir mekanizma kullanarak dağıtabileceğiniz anlamına gelir.
Tarayıcı uzantıları
Bir tarayıcı uzantısının, Aynı Kaynak Politikası uygulanmadan önce yanıtta CORS başlıklarını enjekte etmesi mümkündür.
Bunlar geliştirme için yararlı olabilir, ancak bir üretim sitesi için pratik değildir (sitenizdeki her kullanıcıdan, tarayıcılarının bir güvenlik özelliğini devre dışı bırakan bir tarayıcı uzantısı yüklemesini istemek mantıksızdır).
Ayrıca yalnızca basit isteklerle çalışma eğilimindedirler (ön kontrol SEÇENEKLERİ isteklerini ele alırken başarısız olurlar).
Yerel bir geliştirme sunucusuna sahip uygun bir geliştirme ortamına sahip
olmak genellikle daha iyi bir yaklaşımdır.
Diğer güvenlik riskleri
SOP / CORS'un , bağımsız olarak ele alınması gereken XSS , CSRF veya SQL Injection saldırılarını azaltmadığını unutmayın .
Özet
- Eğer yapabileceğiniz bir şey yoktur senin birileri için CORS erişimini sağlayacak istemci tarafı kodu başka sunucuya.
- Sunucuyu kontrol ediyorsanız, istek şu şekilde yapılır: Ona CORS izinleri ekleyin.
- Onu kontrol eden kişiyle arkadaşça davranıyorsanız: CORS izinleri eklemesini sağlayın.
- Bir kamu hizmetiyse:
- İstemci tarafı JavaScript ile erişim hakkında ne söylediklerini görmek için API belgelerini okuyun:
- Size belirli URL'ler kullanmanızı söyleyebilirler
- JSONP'yi destekleyebilirler
- İstemci tarafı kodundan çapraz kaynaklı erişimi hiç desteklemeyebilirler (bu, özellikle her istekte kişiselleştirilmiş bir API Anahtarı iletmeniz gerekiyorsa, güvenlik gerekçesiyle kasıtlı bir karar olabilir).
- İhtiyacınız olmayan bir ön kontrol talebini tetiklemediğinizden emin olun. API, basit istekler için izin verebilir ancak önceden kontrol edilmiş istekler için izin vermez.
- Yukarıdakilerin hiçbiri geçerli değilse: konuşursan için tarayıcıya sahip olun sizin yerine sunucudan ve sonra sunucu diğer sunucudan veri almaya ve geçirir var. (Ayrıca, kullanabileceğiniz genel olarak erişilebilen kaynaklara CORS başlıklarını ekleyen üçüncü tarafça barındırılan hizmetler de vardır).