CORS nedir ve ne işe yarar?
Bu flood’da ön yüz geliştirmesi ile uğraşmış herkesin muhakkak en az bir kere tarayıcıdan hata alarak karşılaştığı CORS
(Cross Origin Request Sharing
) konseptini anlatacağım.
Tarayıcılar kullanıcıyı korumak üzere kullanıcı bir sitede gezinti yaparken ilgili sitenin başka bir siteye web isteği yapmasına sınırlama getirir. Bu sınırlama Same Origin Policy - SOP
olarak adlandırılır.
SOP
ile tarayıcılar, kötü niyetli xyz․com
'un kullanıcının aynı tarayıcı ile açtığı diğer sitelerdeki bilgileri oturum çerezleri üzerinden çalmasını engellenmiş olur. CORS
işte tam bu noktada SOP
tarafından getirilen sınırlamaları esnetmek üzere ortaya konmuştur.
Aşağıda CORS Policy
tarafından esnetilmediğinde farklı bir origin
'e yapılmaya çalışılan istek sonucu tarayıcının SOP
kısıtlamalarından dolayı isteğe izin vermeyip, geliştirici konsoluna bastığı hataya bir örnek verilmiştir.
CORS
öncesinde başka bir origin
'e istek yapabilmek yani SOP
'u aşabilmek için JSONP
adı verilen yöntem kullanmak gerekirdi. Aslında bir hack
olan bu yöntem ile orijini farklı olan siteye genellikle Ajax
ile kullanılan ve XHR
olarak kısaltılan XMLHttpRequest
isteği atmak yerine, tarayıcı tarafında kaynak olarak uzak sunucuda bulunan URL
'in ve callback
'in verildiği bir <script>
tag'i oluşturulur, ilgili kod bloğu uzak sunucuda çalıştırılır ve sonuç verilen callback
'e iletilir. Böylece SOP
aşılmış olur.
CORS
sayesinde bir orijin kendisine XHR
atabilecek diğer orijinleri, HTTP
başlık ve istek tiplerini (DELETE
, PUT
, vb) granüler olarak belirleyebilir. Bu sayede tarayıcılar tarafından uygulanan katı SOP
kuralları legal kullanımlar için esnetilmiş olur.
Yine ön yüz geliştirmesi ile uğraşan herkesin dikkatini çektiği gibi başka bir orijine atılan isteklerden önce tarayıcı OPTIONS
isteğini atmakta ve karşı tarafın yapılmak istenen isteğe izin verip vermediğini anlamaya çalışmaktadır. Aşağıda bir OPTIONS
örneği verilmiştir.
Yukarıda, tarayıcı OPTIONS
ile sunucuya istemcinin Content-Type
başlığı ile bir POST
isteği atmak için izni olup olmadığını sormuştur. Sunucu cevabında istemcinin sahip olduğu hakları listeyip OK
cevabı vermiştir. Sonrasında sunucuya aşağıda verilen asıl istek atılmıştır.
Bütün web sunucu ve istemcilerin bir anda CORS
desteği kazanabileceği ideal bir dünyada yaşıyor olsaydık yukarıda örneği verilen ve preflight request
olarak adlandırılan OPTIONS
isteğine aslında hiç ihtiyaç duymayacaktık.
OPTIONS
legacy web sunucuların CORS
geçişini güvenlik riski oluşturmadan yapabilmelerini sağlamıştır. preflight request
ile daha önce SOP
sayesinde farklı bir orijinden belirli istekleri almayacağı varsayımı ile çalışan web uygulamaları bu varsayımı sürdürebilmişlerdir.
Tarayıcılar bütün farklı orijinlere yapılan bütün XHR
istekleri için preflight
kontrolü yapmazlar. Simple Request
olarak adlandırılan GET
ve bazı POST
istekleri OPTIONS
olmadan direkt sunucuya gönderilir. Bunun sebebi de yine mevcut uygulamaları bozmamak içindir. CORS
öncesinde de farklı domain'ler arasında form göndermek mümkün olduğu için başlığında Content-Type
olarak application/x-www-form-urlencoded
ve multipart/form-data
bulunan POST
istekleri için OPTIONS
gönderilmez ve böylece mevcut fonksiyonalite kırılmamış olur.
Karşı taraftaki sunucunun CORS
destekli olması durumunda tarayıcı preflight request
göndermemiş olsa bile sunucu GET
ve POST
isteklerinde orijin kontrolü yapabilir ve eğer isteği yapan orijin izin verdiği listede değilse istekleri direkt olarak reddedebilir.
Son olarak cURL
veya benzeri komut satırı istemcilerin OPTIONS
isteği olmadan da sunucuya POST
isteği gönderilebileceğinin altını çizmek gerekir çünkü CORS
ile asıl amaç son kullanıcıyı tehlikelerden koruyarak web uygulamalarının işbirliğine izin vermektir.
Bir sonraki flood’da CORS
'a daha pratik ve pragmatik bir bakış atarak kullanım alanları ile farklı ortamlarda CORS
'u aşma yöntemlerini ele alacağız.