Aynı köken politikasını atlatmanın yolları


150

Aynı menşe politikası

Umarım bu konuyu arayan herkese yardımcı olması için HTML / JS aynı kaynaklı politikalarla ilgili bir topluluk wiki'si yapmak istedim . Bu SO üzerinde en çok aranan konulardan biridir ve bunun için konsolide wiki yoktur, işte buradayım :)

Aynı kaynak ilkesi, bir kaynaktan yüklenen bir belgenin veya komut dosyasının bir belgenin özelliklerini başka bir kaynaktan almasını veya ayarlamasını engeller. Bu politika Netscape Navigator 2.0'a kadar uzanır.

Aynı menşei politikaları dolaşmanın en sevdiğiniz yolları nelerdir?

Lütfen örnekleri ayrıntılı tutun ve tercihen kaynaklarınızı da bağlayın.


4
güzel fikir .. Örneklerinizi cevaplara vermelisiniz; olduğu gibi, soruyu oldukça hantal
yaparlar

1
Ayrıca her yaklaşım için bir güvenlik sonuçları listesi eklemelisiniz. JSONP özel veriler için son derece güvensizdir.
Erlend

Neden yakın? Bu (wiki) soru son 2 yıldır oldukça kullanışlıdır. Ayrıca, birçok cevaplar vardır kaynakla desteklenmelidir. Bir not constructiveetiket tamamen anlamsız göründüğü için bir açıklama takdir edilecektir . Oy verildi yeniden açıldı.
David Titarenco

Yanıtlar:


84

document.domainyöntem

  • Yöntem türü: iframe .

Bunun, document.domain değerini geçerli etki alanının sonekine ayarlayan bir iframe yöntemi olduğunu unutmayın. Bunu yaparsa, daha sonraki etki alanı denetimleri için daha kısa etki alanı kullanılır. Örneğin, adresindeki belgedeki bir komut dosyasının http://store.company.com/dir/other.htmlaşağıdaki ifadeyi yürüttüğünü varsayın :

document.domain = "company.com";

Bu ifade yürütüldükten sonra sayfa başlangıç ​​denetimini ile geçecektir http://company.com/dir/page.html. Ancak, aynı akıl yürütme yoluyla, company.com kuramayacaklarini document.domain için othercompany.com.

Bu yöntemle, javascript'i ana alan adında oluşturulan bir sayfada bir alt alan adından kaynaklı bir iframe'den gerçekleştirmenize izin verilir. Firefox gibi tarayıcılar document.domaintamamen yabancı bir alanı değiştirmenize izin vermeyeceğinden, bu yöntem alanlar arası kaynaklar için uygun değildir .

Kaynak: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript

Kaynaklar Arası Kaynak Paylaşımı yöntemi

  • Yöntem türü: AJAX .

Kaynaklar Arası Kaynak Paylaşımı (CORS), kaynaklardan kaynaklara erişirken tarayıcının ve sunucunun nasıl iletişim kurması gerektiğini tanımlayan bir W3C Çalışma Taslağıdır. CORS'nin arkasındaki temel fikir, hem tarayıcının hem de sunucunun, isteğin veya yanıtın başarılı veya başarısız olup olmadığını belirlemek için birbirlerini yeterince bilmesini sağlamak için özel HTTP üstbilgileri kullanmaktır.

Basit bir istek için, özel üstbilgileri kullanan GETveya POSTiçermeyen ve gövdesi text/plainolan bir istek, çağrı adı verilen ek bir üstbilgiyle gönderilir Origin. Origin başlığı, talep eden sayfanın kaynağını (protokol, etki alanı adı ve bağlantı noktası) içerir, böylece sunucunun bir yanıt sunup sunmayacağını kolayca belirleyebilir. Örnek bir Originbaşlık şöyle görünebilir:

Origin: http://www.stackoverflow.com

Sunucu, isteğe izin verilmesi gerektiğine karar verirse Access-Control-Allow-Origin, gönderilen ile aynı kaynağı veya *ortak bir kaynaksa yankılanan bir başlık gönderir . Örneğin:

Access-Control-Allow-Origin: http://www.stackoverflow.com

Bu üstbilgi eksikse veya orijinler eşleşmiyorsa, tarayıcı isteği reddeder. Her şey yolundaysa, tarayıcı isteği işler. Ne isteklerin ne de yanıtların çerez bilgilerini içermediğini unutmayın.

Mozilla ekibi, CORS hakkındaki yayınlarındawithCredentials , tarayıcının XHR aracılığıyla CORS'i destekleyip desteklemediğini belirlemek için mülkün varlığını kontrol etmeniz gerektiğini önermektedir . Daha sonra XDomainRequesttüm tarayıcıları kapsayacak şekilde nesnenin varlığıyla eşleştirebilirsiniz:

function createCORSRequest(method, url){
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr){
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined"){
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}

var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
    request.onload = function() {
        // ...
    };
    request.onreadystatechange = handler;
    request.send();
}

CORS yönteminin çalışması için herhangi bir sunucu üstbilgisi tamircisine erişiminizin olması gerektiğini ve herhangi bir üçüncü taraf kaynağına erişemeyeceğinizi unutmayın.

Kaynak: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/

window.postMessageyöntem

  • Yöntem türü: iframe .

window.postMessage, çağrıldığında, MessageEventyürütülmesi gereken herhangi bir komut dosyası tamamlandığında (örn window.postMessage. bir olay işleyiciden çağrılırsa kalan olay işleyicileri, önceden ayarlanmış bekleyen zaman aşımları, vb.) hedef pencerede a gönderilmesine neden olur . MessageEventTip mesaj, bir var datasağlanan ilk argüman dize değerine ayarlanır özelliği window.postMessagebir, originçağıran pencerede ana belgenin kökeni karşılık gelen özellik window.postMessagezamanda window.postMessageçağrıldı ve sourcepencere dan mülk hangi window.postMessagedenir.

Kullanmak için window.postMessagebir olay dinleyicisi eklenmelidir:

    // Internet Explorer
    window.attachEvent('onmessage',receiveMessage);

    // Opera/Mozilla/Webkit
    window.addEventListener("message", receiveMessage, false);

Ve bir receiveMessageişlev bildirilmelidir:

function receiveMessage(event)
{
    // do something with event.data;
}

Site dışı iframe ayrıca etkinlikleri şu yollarla doğru bir şekilde göndermelidir postMessage:

<script>window.parent.postMessage('foo','*')</script>

Herhangi bir pencere, belgenin penceredeki konumuna bakılmaksızın, kendisine mesaj göndermek için herhangi bir zamanda başka bir pencerede bu yönteme erişebilir. Sonuç olarak, iletileri almak için kullanılan herhangi bir olay dinleyicisi, önce kaynak ve olası kaynak özelliklerini kullanarak iletiyi gönderenin kimliğini kontrol etmelidir. Bu önemsiz olamaz: ve muhtemelen özelliklerinin kontrol edilmemesi siteler arası komut dosyası saldırılarına olanak tanır.originsource

Kaynak: https://developer.mozilla.org/en/DOM/window.post



Umarım cevap almak için çok geç değilim: sadece soru şu ki, localhost DAİMA bir istisna mı? her zaman izin verilmiyor mu? localhost'um aracılığıyla test yapmayı bırakmalı mıyım?
Ayyash

1
Neden emin değilim ama ayarladığımda: Access-Control-Allow-Origin: http://www.stackoverflow.com/yerine: Access-Control-Allow-Origin: http://www.stackoverflow.com(url sonunda eğik çizgi), Safari ve FF'de çalışmaz, ancak Chrome'da çalışır. Elbette eğik çizgi olmadan tüm tarayıcılarda iyi çalışır.
mtfk

1
postMessageBir HTML5 eklentisi olduğu için , yöntemin yalnızca onu destekleyen tarayıcılar için işe yaradığını bilmeye değer olabilir . Bu eklenti bunun hesabını vermeye çalışıyor. Sadece bundan bahsetmek çünkü bunu zor yoldan öğreniyorum.
IronicMuffin

41

Ters Proxy yöntemi

  • Yöntem türü: Ajax

Sunucuda basit bir ters proxy kurmak , tarayıcının Ajax istekleri için göreli yollar kullanmasına izin verirken, sunucu herhangi bir uzak konuma proxy görevi görür.

Apache'de mod_proxy kullanılıyorsa , ters proxy ayarlamak için temel yapılandırma direktifidir ProxyPass. Genellikle aşağıdaki gibi kullanılır:

ProxyPass     /ajax/     http://other-domain.com/ajax/

Bu durumda, tarayıcı /ajax/web_service.xmlgöreli URL olarak istekte bulunabilir , ancak sunucu buna proxy olarak davranarak hizmet eder http://other-domain.com/ajax/web_service.xml.

Bu yöntemin ilginç bir özelliği, ters proxy'nin istekleri birden çok arka uca kolayca dağıtabilmesi ve böylece bir yük dengeleyici görevi görmesidir .


17

JSONP kullanıyorum.

Temel olarak,

<script src="http://..../someData.js?callback=some_func"/>

sayfanda.

Verinin bulunduğu konusunda bilgilendirilmeniz için some_func () çağrılmalıdır.


7
JSONP'un iki sorunu vardır: a) Hedef etki alanına bir komut dosyası etiketi ekliyorsunuz. Düzenli javascript (XSS saldırısı) bile her şeyi geri gönderebilirler. Bu nedenle, kötü şeyler yapmamaları veya saldırıya uğramamaları için onlara güvenmeniz gerekir b) Başka herhangi bir web sayfası aynı komut dosyası etiketini ekleyebilir ve verileri çalabilir, bu nedenle özel veriler için asla JSONP kullanmayın.
Erlend

1
@Erlend: Web'de sunulan tüm bilgiler herkes tarafından alınabilir (doğru kimlik doğrulaması gerekmedikçe). Bu bilgilerin nasıl sunulduğunun kesin biçimi JSONP olsa bile bunu daha iyi veya daha kötü yapmaz.
T-Bull

2
@ T-Bull: Sorun, JSONP ile doğru kimlik doğrulamasının imkansız olmasıdır. Bir kullanıcı A sitesinde oturum açar ve bir JSONP komut dosyası etiketi kullanarak A'dan veri yükleyen B sitesine gider. İyi ve iyi olduğu gibi. Daha sonra kullanıcı, A'dan veri yüklemek için bir JSONP komut dosyası etiketi kullanan kötü site C'yi ziyaret etmek için kandırılır. Bu nedenle, kullanıcının A ile kimliği doğrulandığı için, C'nin sahibi artık A'dan gelen verileri çalabilir. kullanıcı A ile kimlik doğrulaması için iki faktörlü kimlik doğrulama kullandı. Sorun JSONP'nin güvensiz olması. JSONP sunum değildir. Güvenli olmayan veri aktarımı.
Erlend

1
JSONP yalnızca HTTP GET'i destekler.
opyate

Bu .js dosyası neyi temsil ediyor -> "http: //..../someData.js.... dom'u başka bir site istemci tarafından okumaya çalışıyorum ve aynı köken politikasını atlatmam gerekiyor .
CS_2013

13

AnyOrigin bazı https siteleriyle iyi çalışmadı, bu yüzden sadece https ile iyi çalışıyor gibi görünen whateverorigin.org adlı açık kaynaklı bir alternatif yazdım .

Github üzerine kod .


@DavidTitarenco - anyorigin'in karnında olan bazı şeyleri anlamaya çalışmak beni deli etti. Neyse ki yardımcı olan bir blog yazısı buldum ve şimdi bir sonraki adamın ihtiyacı olursa çalışan bir test sitesi olacak.
ripper234

@neoascetic - kullanım düzeltildi ... URL'nin şimdi kodlanması gerekiyor.
ripper234

12

Bulduğum menşe politikasının üstesinden gelmenin en yeni yolu http://anyorigin.com/

Site sadece herhangi bir url vermek ve böylece kökeni ne olursa olsun, html / veri elde etmenizi sağlayan javascript / jquery kodu üretir. Başka bir deyişle, herhangi bir URL'yi veya web sayfasını JSONP isteği yapar.

Oldukça kullanışlı buldum :)

Anyorigin bazı örnek javascript kodu:

$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
    $('#output').html(data.contents);
});

Her ne kadar https siteleriyle ilgili bazı sorunlar verdi, bu yüzden aşağıdaki açık kaynak alternatifime
göz atın

13
Bu şu anlama gelir: a) anyorigin, tem yoluyla aktarılan tüm verilerinizi okuyabilecektir b) anyorigin sitenizi XSS yapabilir, sitenizdeki tüm verilerinizi okuyabilir ve kullanıcılarınıza kötü amaçlı yazılım gönderebilir (anyorigin saldırıya uğramışsa ne olur?)
Erlend

@Erlend - fork Whateverorigin ve kendi sunucunuzda barındırın. Kod önemsiz olduğundan, orada hiçbir açıklamanın gizlenmediğinden emin olmak için inceleyebilirsiniz.
ripper234


3

JSONP akla gelen:

JSONP veya "dolgu ile JSON", bir sayfanın birincil sunucu dışındaki bir sunucudan JSON istemesini ve daha anlamlı olarak kullanmasını sağlayan bir kullanım modeli olan temel JSON veri biçiminin bir tamamlayıcısıdır. JSONP, Kaynaklar Arası Kaynak Paylaşımı adı verilen daha yeni bir yönteme alternatiftir.


Yukarıdaki JSONP hakkındaki yorumuma bakın. Özel veriler için iyi bir seçim değil.
Erlend

1

Şahsen, window.postMessagemodern tarayıcılar için bulduğum en güvenilir yol. Kendinizi XSS saldırılarına açık bırakmadığınızdan emin olmak için biraz daha fazla iş yapmanız gerekiyor, ancak bu makul bir ödünleşim.

Popüler Javascript araç takımları için, window.postMessageyukarıda tartışılan diğer yöntemleri kullanarak eski tarayıcılara benzer işlevler sağlayan birkaç eklenti de vardır .


1

Bunu atlatmak için PHP'de curl kullandım. 82 numaralı bağlantı noktasında çalışan bir web hizmetim var.

<?php

$curl = curl_init();
$timeout = 30;
$ret = "";
$url="http://localhost:82/put_val?val=".$_GET["val"];
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl, CURLOPT_MAXREDIRS, 20);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5");
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
$text = curl_exec($curl);
echo $text;

?>

İşte PHP dosyasına çağrı yapan javascript

function getdata(obj1, obj2) {

    var xmlhttp;

    if (window.XMLHttpRequest)
            xmlhttp=new XMLHttpRequest();
    else
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
                document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET","phpURLFile.php?eqp="+obj1+"&val="+obj2,true);
    xmlhttp.send();
}

HTML'm bağlantı noktası 80'de WAMP üzerinde çalışıyor. İşte başlıyoruz, aynı köken politikası atlatıldı :-)



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.