Aynı Kök Politikası

Aynı kök politikası web uygulamaları güvenlik modelinde önemli bir unsurdur. Bu politikaya göre, bir web tarayıcısı, bir web sayfasında yer alan betiklerin ikinci bir web sayfası üzerindeki veriye erişimine sadece bu iki sayfa aynı köke sahipse izin vermektedir. Bir kök, URI şeması, hostname ve port numarasının bir kombinasyonu olarak tanımlanmaktadır. Bu politika, bir sayfada bulunan kötücül betiğin başka bir sayfada bulunan hassas verilere erişimini, o sayfanın Belge Nesnesi Modeli aracılığıyla engellemektedir.

Bu mekanizma, kimlik doğrulaması yapılmış kullanıcı oturumlarını yönetmek için yoğun bir şekilde HTTP çerezlerine dayanan modern uygulamalar için özel bir önem taşımaktadır. Bunun nedeni, sunucuların hassas bilgileri göndermek ve durum değiştiren aktiviteleri yapmak için HTTP çerez bilgilerine dayanmasıdır. Birbiri ile bağlantısı olmayan sitelerin sağladığı içerikler arasında betik ayırımı, gizlilik ve bütünlük açısından herhangi bir kayba neden olunmaması için istemci tarafında yapılmalıdır.

Aynı kök politikası kavramı 1995 yılındaki Netscape Navigator 2'ye dayanmaktadır. Bu politika başlarda Belge Nesnesi Modeline (DOM) erişimi korumak için tasarlanmış olsa da, kök JavaScript nesnelerinin hassas kısımlarını koruyacak şekilde genişletilmiştir.

Bütün modern tarayıcılar, güvenlik açısından önemli bir temel taşı olduğu için bir şekilde Aynı Kök Politikası'nı uygulamaktadır. Bu politikalar kesin bir tanıma uymak zorunda değildir, ancak genelde Microsoft Silverlight, Adobe Flash veya Adobe Acrobat gibi diğer web teknolojileri için veya XMLHttpRequest gibi doğrudan DOM değişimi için olmayan diğer mekanizmalar için, kabaca uyarlanabilir güvenlik sınırları tanımlayacak şekilde genişletilmiştir.

bir URI'ye ait "kök" belirlenirken kullanılan algoritma RFC 6454'ün 4. Kısmı'nda tanımlanmaktadır. Tam URI'ler için {protokol, host, port} üçlüsü köktür. Eğer URI bir isimlendirme otoritesi (RFC 3986 3.2. Kısma bakınız) olarak hiyerarşik bir yapı kullanmıyorsa veya URI bir tam URI değilse, genel benzersiz tanımlayıcı (GUID) kullanılır. İki kaynak sadece ve sadece tüm bu değerler birebir aynı ise aynı kökten sayılmaktadır.

Aynı kök politikası, kimlik doğrulaması yapılmış oturumları kullanan sitelerin korunmasına yardım etmektedir. Bahsedilecek örnek, aynı kök politikası olmadığında oluşabilecek olası güvenlik riskini örneklemektedir. Bir kullanıcının bir bankacılık uygulamasını kullandığını ve sonrasında çıkış yapmadığını varsayalım. Sonrasında kullanıcı, bankacılık sitesinden veri isteyen ve arka planda çalışan kötücül JavaScript kodu çalıştıran başka bir siteye gitmiştir. Kullanıcı bankacılık uygulamasında oturumunu kapatmadığı için, kötücül kod kullanıcının bankacılık sitesi üzerinde yapabileceği her şeyi yapabilmektedir. Örneğin, kullanıcının son işlemlerini listeleyebilir, yeni bir işlem yapabilir, vb. Bunun nedeni, tarayıcının bankacılık sitesinin alan adına bağlı olarak bankacılık sitesine oturum çerezlerini gönderebilmesi ve oturum çerezleri alabilmesidir.

Kötücül siteyi ziyaret eden kullanıcı, ziyaret ettiği sitenin bankacılık oturum çerezlerine erişemeyeceğini beklemektedir. JavaScript kodunun doğrudan bankacılık uygulaması çerezlerine erişiminin olmadığı doğru olsa da, yine de bankacılık sitesinin oturum çerezleri ile bankacılık sitesine istek gönderebilmekte ve bu siteden cevap alabilmektedir. Betik temelde kullanıcının yapabileceği her şeyi yapabildiği için, bankacılık sitesi tarafından uygulanan CSRF koruma yöntemleri bile faydasız olmaktadır.

Eğer iki pencere (veya çerçeve) alan adını aynı değer olarak belirleyen betikler içeriyorsa, bu iki pencere için aynı kök politikası esnetilir ve pencereler birbirleriyle haberleşebilir. Örneğin, orders.example.com ve catalog.example.com üzerinden yüklenen dokümanlardaki betikler, document.domain özelliklerini "example.com" olarak belirleyebilir ve böylece dokümanların aynı kökü paylaşmasını ve her bir dokümanın diğerinin özelliklerini okuyabilmesini sağlayabilirler. Bu, iç tarafta saklanan port değerinin null olarak işaretlenebilmesinden dolayı her zaman çalışmayabilmektedir. Başka bir deyişle, example.com port 80, document.domain özelliği güncellendiği için example.com port null olarak değişebilmektedir. Port null 80 portu gibi muamele görmeyebilir (tarayıcıya bağlı olarak) ve böylece geçersiz olabilir veya tarayıcıya bağlı olarak başarılı olabilir.

Aynı kök politikasının esnetilmesi için ikinci bir yöntem, Köklar Arası Kaynak Paylaşımı ismi ile standardize edilmiştir. Bu standart, HTTP protokolünü yeni Origin istek başlığı ve Access-Control-Allow-Origin cevap başlığı ile genişletmiştir. Bu, sunucuların bir başlık kullanarak bir dosyaya erişebilecek kökleri listelemesine veya özel bir karakter (*) kullanarak bir dosyayı herhangi bir sitenin erişimine açmasına izin vermektedir. Firefox 3.5, Safari 4 ve Internet Explorer 10 gibi tarayıcılar, aksi takdirde aynı kök politikası tarafından engellenecek olan XMLHttpRequest ile kökler arası HTTP isteklerine izin vermek için bu başlığı kullanmaktadır.

Başka bir teknik olan dokümanlar arası mesajlaşma, bir sayfadaki betiğin betik köklerinden bağımsız olarak başka bir sayfadaki betiğe metinsel mesajlar göndermesine izin vermektedir. Bir Window nesnesi üzerinden postMessage() metodunun çağrılması, eşzamansız olarak o window nesnesi üzerinde bir "onmessage" olayı oluşturur ve kullanıcının tanımladığı olay işleyicileri tetikler. Bir sayfadaki betik, başka bir sayfadaki metot ve değişkenlere doğrudan erişemez, ancak bu mesaj gönderme mekanizması üzerinden güvenli bir şekilde haberleşebilirler.

JSONP bir sayfanın, başka bir alan adından bir JSON cevabı yükleyen sayfaya <script> elemanının eklenmesi ile farklı bir alan adından JSON verisi almasına izin vermektedir.

Modern tarayıcılar, aynı kök politikasını uygulamaksızın bir betiğin bir WebSocket adresine bağlanmasına izin vermektedir. Ancak, bir WebSocket URI'sinin kullanıldığını anlamakta ve isteğe, bağlantıyı isteyen betiğin kökünü belirten bir Origin: başlığı eklemektedir. Siteler arası güvenliği sağlamak için, WebSocket sunucusu başlık verisini cevap almasına izin verilen köklerden oluşan bir beyaz liste ile karşılaştırmalıdır.

Aynı kök politikası kontrollerinin ve ilgili mekanizmaların davranışı, URL'leri (file:, data:, vb.) ile ilişkilendirilen açıkça tanımlanmış bir alan adı veya port bilgisine sahip olmayan sözde protokoller için olduğu gibi bazı uç örneklerde kesin bir şekilde tanımlanmamıştır. Bu durum, lokal olarak saklanan HTML dosyasının disk üzerindeki diğer dosyalara erişebilmesi veya İnternet üzerindeki herhangi bir site ile haberleşebilmesi gibi genellikle istenmeyen yetenekler gibi hatırı sayılır miktarda güvenlik problemlerine neden olmuştur.

İlave olarak, JavaScript'ten önce var olan pek çok siteler arası işlemler aynı kök kontrollerine tabii olmamaktadır; buna bir örnek alan adları arasında betiklerin dahil edilebilmesi veya POST formlarının gönderilebilmesi yeteneğidir.

Son olarak, DNS re binding saldırıları veya sunucu taraflı vekil sunucular gibi bazı saldırı türleri, alan adı kontrolünün kısmen atlatılabilmesine izin vermekte ve sahte web sayfalarının, "gerçek", canonical kökünden farklı başka adresler üzerinden doğrudan sitelerle etkileşimde bulunabilmesini mümkün kılmaktadır. Bu tür saldırıların etkisi, çok özel durumlarla sınırlıdır. Çünkü tarayıcı hala saldırganın sitesiyle haberleştiğine inanmaktadır ve bu yüzden üçüncü taraf çerezleri veya diğer hassas bilgileri saldırgana ifşa etmemektedir.

Geliştiricilerin kontrollü bir şekilde aynı kök politikasını atlatabilmesini mümkün kılmak için, fragman tanımlayıcının veya window.name özelliğinin kullanılması gibi bir takım yöntemler, farklı alan adlarında bulunan dokümanlar arasında veri gönderiminde kullanılmaktadır. HTML5 standardıyla, yeni tarayıcılarda kullanılabilir olan bir yöntem postMessage arayüzü, resmileştirilmiştir.  JSONP de diğer alan adlarına yapılan Ajax benzeri çağrıları aktif hale getirmek için kullanılabilmektedir.