วิธีหลีกเลี่ยงนโยบายที่มาเดียวกัน


150

นโยบายกำเนิดเดียวกัน

ฉันต้องการสร้างวิกิชุมชนเกี่ยวกับนโยบาย HTML / JS เดียวกันเพื่อหวังว่าจะช่วยให้ทุกคนค้นหาหัวข้อนี้ได้ นี่เป็นหนึ่งในหัวข้อที่ค้นหามากที่สุดใน SO และไม่มีวิกิรวมไว้ด้วยดังนั้นที่นี่ฉันไป :)

นโยบายกำเนิดเดียวกันป้องกันเอกสารหรือสคริปต์ที่โหลดจากจุดเริ่มต้นหนึ่งจากการรับหรือการตั้งค่าคุณสมบัติของเอกสารจากจุดกำเนิดอื่น นโยบายนี้มีอายุย้อนกลับไปที่ Netscape Navigator 2.0

อะไรคือวิธีที่คุณโปรดปรานในการใช้นโยบายต้นกำเนิดเดียวกัน

โปรดเก็บตัวอย่าง verbose และควรเชื่อมโยงแหล่งที่มาของคุณด้วย


4
เป็นความคิดที่ดี .. คุณควรใส่ตัวอย่างไว้ในคำตอบ ตามที่ตั้งไว้พวกเขาทำคำถามค่อนข้างใหญ่
Shog9

1
คุณควรเพิ่มรายการผลกระทบด้านความปลอดภัยสำหรับแต่ละวิธี JSONP มีความไม่ปลอดภัยสูงสำหรับข้อมูลส่วนตัว
Erlend

ทำไมต้องปิด คำถาม (วิกิ) นี้มีประโยชน์มากสำหรับ 2 ปีที่ผ่านมา นอกจากนี้คำตอบมากมายได้รับการสนับสนุนโดยการอ้างอิง คำอธิบายจะได้รับการชื่นชมเป็นnot constructiveแท็กที่ดูเหมือนว่าบ้าอย่างเต็มที่ โหวตให้เปิดใหม่
David Titarenco

คำตอบ:


84

document.domainวิธี

  • ประเภทวิธีการ: iframe

โปรดทราบว่านี่เป็นวิธี iframe ที่ตั้งค่า document.domain เป็นส่วนต่อท้ายของโดเมนปัจจุบัน หากเป็นเช่นนั้นโดเมนที่สั้นกว่าจะถูกใช้สำหรับการตรวจสอบต้นฉบับ ตัวอย่างเช่นสมมติว่าสคริปต์ในเอกสารที่http://store.company.com/dir/other.htmlดำเนินการคำสั่งต่อไปนี้:

document.domain = "company.com";

http://company.com/dir/page.htmlหลังจากนั้นรันคำสั่งหน้าจะผ่านการตรวจสอบแหล่งที่มาด้วย แต่ด้วยเหตุผลเดียวกัน company.com อาจไม่ได้ตั้งค่าการdocument.domain othercompany.com

ด้วยวิธีนี้คุณจะได้รับอนุญาตให้ออกจากจาวาสคริปต์จาก iframe ที่มาจากโดเมนย่อยบนหน้าเว็บที่มาจากโดเมนหลัก วิธีนี้ไม่เหมาะสำหรับทรัพยากรข้ามโดเมนเนื่องจากเบราว์เซอร์เช่น Firefox จะไม่อนุญาตให้คุณเปลี่ยนdocument.domainไปเป็นโดเมนต่างด้าวทั้งหมด

ที่มา: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript

วิธีการใช้ทรัพยากรร่วมกันข้ามแหล่งกำเนิด

  • ประเภทวิธีการ: AJAX

การแบ่งปันทรัพยากรข้ามแหล่งกำเนิด (CORS) เป็น W3C Working Draft ที่กำหนดวิธีที่เบราว์เซอร์และเซิร์ฟเวอร์ต้องสื่อสารเมื่อเข้าถึงแหล่งข้อมูลข้ามแหล่งกำเนิด แนวคิดพื้นฐานเบื้องหลัง CORS คือการใช้ส่วนหัว HTTP ที่กำหนดเองเพื่ออนุญาตให้ทั้งเบราว์เซอร์และเซิร์ฟเวอร์รู้จักกันพอสมควรเพื่อพิจารณาว่าคำขอหรือการตอบสนองควรสำเร็จหรือล้มเหลว

สำหรับคำขอที่เรียบง่ายอย่างใดอย่างหนึ่งที่ใช้อย่างใดอย่างหนึ่งGETหรือPOSTมีส่วนหัวที่กำหนดเองไม่ได้และมีร่างกายคำขอถูกส่งไปพร้อมกับหัวพิเศษที่เรียกว่าtext/plain Originส่วนหัวของ Origin ประกอบด้วยจุดเริ่มต้น (โปรโตคอลชื่อโดเมนและพอร์ต) ของหน้าการร้องขอเพื่อให้เซิร์ฟเวอร์สามารถระบุได้อย่างง่ายดายว่าควรตอบสนองหรือไม่ Originส่วนหัวตัวอย่างอาจมีลักษณะเช่นนี้:

Origin: http://www.stackoverflow.com

หากเซิร์ฟเวอร์ตัดสินใจว่าควรอนุญาตให้ส่งคำขอจะส่งAccess-Control-Allow-Originส่วนหัวที่สะท้อนต้นกำเนิดเดียวกันกับที่ส่งมาหรือ*เป็นทรัพยากรสาธารณะ ตัวอย่างเช่น:

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

หากส่วนหัวนี้หายไปหรือต้นกำเนิดไม่ตรงกันเบราว์เซอร์จะปิดการร้องขอ หากทุกอย่างเรียบร้อยเบราว์เซอร์จะดำเนินการตามคำขอ โปรดทราบว่าคำขอหรือคำตอบไม่รวมถึงข้อมูลคุกกี้

ทีมงาน Mozilla แนะนำในโพสต์เกี่ยวกับ CORSว่าคุณควรตรวจสอบการมีอยู่ของwithCredentials คุณสมบัติเพื่อดูว่าเบราว์เซอร์รองรับ CORS ผ่าน XHR หรือไม่ จากนั้นคุณสามารถจับคู่กับการมีอยู่ของXDomainRequestวัตถุเพื่อให้ครอบคลุมเบราว์เซอร์ทั้งหมด:

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 คุณจำเป็นต้องเข้าถึงกลไกส่วนหัวของเซิร์ฟเวอร์ประเภทใดก็ได้และไม่สามารถเข้าถึงทรัพยากรบุคคลที่สามใด ๆ

ที่มา: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/

window.postMessageวิธี

  • ประเภทวิธีการ: iframe

window.postMessageเมื่อเรียกจะทำให้ a MessageEventถูกส่งไปที่หน้าต่างเป้าหมายเมื่อสคริปต์ที่รอดำเนินการใด ๆ ที่ต้องดำเนินการเสร็จสมบูรณ์ (เช่นตัวจัดการเหตุการณ์ที่เหลืออยู่หากwindow.postMessageถูกเรียกจากตัวจัดการเหตุการณ์ MessageEventมีข้อความชนิดมีdataคุณสมบัติที่ถูกกำหนดให้เป็นค่าสตริงของอาร์กิวเมนต์แรกให้กับwindow.postMessageการoriginคุณสมบัติที่สอดคล้องกับที่มาของเอกสารหลักในหน้าต่างการเรียกwindow.postMessageในเวลาที่window.postMessageถูกเรียกและsourceทรัพย์สินซึ่งเป็นหน้าต่างจาก ซึ่งwindow.postMessageเรียกว่า

วิธีใช้window.postMessageต้องแนบ listener เหตุการณ์:

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

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

และreceiveMessageฟังก์ชั่นจะต้องประกาศ:

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

iframe นอกไซต์ต้องส่งเหตุการณ์อย่างเหมาะสมผ่านpostMessage:

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

หน้าต่างใด ๆ สามารถเข้าถึงวิธีนี้ในหน้าต่างอื่น ๆ ได้ทุกเวลาโดยไม่คำนึงถึงตำแหน่งของเอกสารในหน้าต่างเพื่อส่งข้อความ ดังนั้นผู้ฟังเหตุการณ์ใด ๆ ที่ใช้ในการรับข้อความต้องตรวจสอบตัวตนของผู้ส่งข้อความก่อนโดยใช้คุณสมบัติต้นทางและคุณสมบัติของแหล่งที่มา สิ่งนี้ไม่สามารถอธิบายได้: ความล้มเหลวในการตรวจสอบoriginและsourceคุณสมบัติที่เป็นไปได้ทำให้เกิดการโจมตีสคริปต์ข้ามไซต์

ที่มา: https://developer.mozilla.org/en/DOM/window.postMessage



ฉันหวังว่าฉันจะไม่สายเกินไปที่จะได้รับคำตอบ: โดยคำถามเท่านั้นคือ localhost อยู่เสมอยกเว้น? ไม่อนุญาตหรือไม่ ฉันควรหยุดการทดสอบผ่าน localhost ของฉัน
Ayyash

1
ฉันไม่แน่ใจว่าทำไม แต่เมื่อฉันตั้งค่า: Access-Control-Allow-Origin: http://www.stackoverflow.com/แทนที่จะ: Access-Control-Allow-Origin: http://www.stackoverflow.com(เฉือนที่ส่วนท้ายของ URL) มันไม่ทำงานใน Safari และ FF แต่ทำงานใน Chrome แน่นอนว่าไม่มีสแลชทำงานได้ดีในเบราว์เซอร์ทั้งหมด
mtfk

1
อาจคุ้มค่าที่จะให้คนอื่นรู้ว่าpostMessageวิธีนี้ใช้ได้กับเบราว์เซอร์ที่รองรับเท่านั้นเนื่องจากเป็นการเพิ่ม HTML5 ปลั๊กอินนี้พยายามที่จะบัญชีสำหรับที่ เพียงกล่าวถึงเพราะฉันเรียนรู้วิธีนี้ยาก
IronicMuffin

41

วิธีการ Reverse Proxy

  • ประเภทวิธีการ: Ajax

การตั้งค่าพร็อกซีย้อนกลับแบบง่ายบนเซิร์ฟเวอร์จะอนุญาตให้เบราว์เซอร์ใช้เส้นทางแบบสัมพันธ์สำหรับคำขอ Ajax ในขณะที่เซิร์ฟเวอร์จะทำหน้าที่เป็นพร็อกซีไปยังตำแหน่งระยะไกล

ถ้าใช้mod_proxyใน Apache, ProxyPassคำสั่งกำหนดค่าพื้นฐานในการตั้งค่าพร็อกซีกลับเป็น มันถูกใช้โดยทั่วไปดังนี้:

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

ในกรณีนี้เบราว์เซอร์จะสามารถที่จะขอ/ajax/web_service.xmlเป็น URL ญาติ http://other-domain.com/ajax/web_service.xmlแต่เซิร์ฟเวอร์จะทำหน้าที่นี้โดยทำหน้าที่เป็นพร็อกซี่ไป

หนึ่งคุณลักษณะที่น่าสนใจของวิธีนี้คือพร็อกซีย้อนกลับสามารถกระจายการร้องขอต่อหลายหลังปลายจึงทำหน้าที่เป็นbalancer โหลด


17

ฉันใช้ JSONP

โดยทั่วไปคุณเพิ่ม

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

บนหน้าของคุณ

some_func () ควรถูกเรียกเพื่อให้คุณได้รับแจ้งว่ามีข้อมูลอยู่


7
JSONP มีสองปัญหา: ก) คุณกำลังเพิ่มแท็กสคริปต์ในโดเมนเป้าหมาย พวกเขาสามารถส่งอะไรกลับแม้แต่จาวาสคริปต์ปกติ (การโจมตี XSS) ดังนั้นคุณต้องเชื่อใจพวกเขาว่าอย่าทำสิ่งที่ไม่ดีหรือถูกแฮ็กข) หน้าเว็บอื่น ๆ สามารถเพิ่มแท็กสคริปต์เดียวกันและขโมยข้อมูลได้ดังนั้นจึงไม่เคยใช้ JSONP สำหรับข้อมูลส่วนตัว
Erlend

1
@Erlend: ข้อมูลใด ๆ ที่ให้บริการบนเว็บสามารถเรียกคืนได้โดยทุกคน (ยกเว้นว่าจำเป็นต้องมีการตรวจสอบความถูกต้องที่เหมาะสม) รูปแบบที่แน่นอนของวิธีการนำเสนอข้อมูลนั้นไม่ได้ทำให้ดีขึ้นหรือแย่ลงแม้ว่าจะเป็น JSONP ก็ตาม
T-Bull

2
@ T-Bull: ปัญหาคือการตรวจสอบความถูกต้องเป็นไปไม่ได้กับ JSONP ผู้ใช้ล็อกอินในไซต์ A จากนั้นไปที่ไซต์ B ซึ่งโหลดข้อมูลจาก A โดยใช้แท็กสคริปต์ JSONP เป็นอย่างดีและดี จากนั้นผู้ใช้จะถูกหลอกให้เข้าเยี่ยมชมเว็บไซต์ที่ชั่วร้าย C ซึ่งใช้แท็กสคริปต์ JSONP เพื่อโหลดข้อมูลจาก A ดังนั้นเนื่องจากผู้ใช้รับรองความถูกต้องด้วย A เจ้าของ C จึงสามารถขโมยข้อมูลผู้ใช้จาก A และแม้ว่า ผู้ใช้ใช้การพิสูจน์ตัวตนแบบสองปัจจัยเพื่อพิสูจน์ตัวตนด้วย A ปัญหาคือ JSONP ไม่ปลอดภัยอย่างมาก และ JSONP ไม่มีการนำเสนอ มันเป็นการถ่ายโอนข้อมูลที่ไม่ปลอดภัย
Erlend

1
JSONP รองรับ HTTP GET เท่านั้น
opyate

ไฟล์. js นี้แสดงถึงอะไร -> "http: //..../someData.js.... ฉันกำลังพยายามอ่าน dom จากฝั่งไคลเอ็นต์ไซต์อื่นและต้องการหลีกเลี่ยงนโยบายต้นทางเดียวกัน .
CS_2013

13

AnyOrigin ไม่ได้ทำงานได้ดีกับบางเว็บไซต์ https ดังนั้นฉันเพิ่งเขียนเป็นทางเลือกที่มาเปิดที่เรียกว่าwhateverorigin.orgที่ดูเหมือนว่าจะทำงานได้ดีกับ https

โค้ดบน GitHub


@DavidTitarenco - มันทำให้ฉันบ้าพยายามที่จะเข้าใจบางสิ่งที่เกิดขึ้นในท้องของชนเผ่าพื้นเมือง โชคดีที่ฉันพบโพสต์บล็อกที่ช่วยได้และตอนนี้คนต่อไปจะมีไซต์ทดสอบที่ใช้งานได้ถ้าเขาต้องการ
ripper234

@neoascetic - แก้ไขการใช้งาน ... ต้องเข้ารหัส URL ทันที
ripper234

12

วิธีล่าสุดในการเอาชนะนโยบายดั้งเดิมที่ฉันพบคือhttp://anyorigin.com/

เว็บไซต์สร้างขึ้นเพื่อให้คุณใส่ URL และสร้างโค้ด javascript / jquery ให้คุณเพื่อให้คุณได้รับ html / data โดยไม่คำนึงถึงที่มา กล่าวอีกนัยหนึ่งมันทำให้ url หรือเว็บเพจใด ๆ เป็นคำขอ JSONP

ฉันคิดว่ามันมีประโยชน์มาก :)

นี่คือตัวอย่างโค้ดจาวาสคริปต์จาก anyorigin:

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

แม้ว่ามันจะทำให้ฉันมีปัญหากับเว็บไซต์ https ดังนั้นลองดูทางเลือกของโอเพนซอร์ซข้างล่างนี้: stackoverflow.com/questions/3076414/…
ripper234

13
ซึ่งหมายความว่าก) anyorigin จะสามารถอ่านข้อมูลทั้งหมดของคุณโอนผ่าน TEM ข) anyorigin สามารถ XSS เว็บไซต์ของคุณอ่านข้อมูลทั้งหมดของคุณบนเว็บไซต์ของคุณและส่งมัลแวร์ให้กับผู้ใช้ของคุณ (เกิดอะไรขึ้นถ้า anyorigin ถูกแฮ็ก)?
Erlend

@Erlend - แยกอะไรก็ตามที่เป็นโฮสต์และโฮสต์ไว้บนเซิร์ฟเวอร์ของคุณเอง รหัสนั้นเล็กน้อยเพื่อให้คุณสามารถตรวจสอบได้เพื่อให้แน่ใจว่าไม่มีช่องโหว่ที่ซ่อนอยู่
ripper234


3

JSONPมาถึงใจ:

JSONP หรือ "JSON with padding" เป็นส่วนเสริมของรูปแบบข้อมูล JSON พื้นฐานรูปแบบการใช้งานที่อนุญาตให้เพจร้องขอและใช้ JSON จากเซิร์ฟเวอร์อื่นที่ไม่ใช่เซิร์ฟเวอร์หลักอย่างมีความหมาย JSONP เป็นอีกทางเลือกหนึ่งของวิธีการล่าสุดที่เรียกว่าการแบ่งปันทรัพยากรข้ามแหล่งกำเนิด


ดูความคิดเห็นของฉันเพื่อ JSONP ด้านบน ไม่ใช่ตัวเลือกที่ดีสำหรับข้อมูลส่วนตัว
Erlend

1

โดยส่วนตัวแล้วwindow.postMessageเป็นวิธีที่น่าเชื่อถือที่สุดที่ฉันพบสำหรับเบราว์เซอร์ที่ทันสมัย คุณต้องทำงานเพิ่มอีกเล็กน้อยเพื่อให้แน่ใจว่าคุณไม่ได้ปล่อยให้ตัวเองเปิดการโจมตี XSS แต่เป็นการแลกเปลี่ยนที่สมเหตุสมผล

นอกจากนี้ยังมีปลั๊กอินต่าง ๆ สำหรับเครื่องมือ Javascript ที่ได้รับความนิยมออกมาที่นั่นซึ่งรวมwindow.postMessageฟังก์ชันการทำงานที่คล้ายกับเบราว์เซอร์รุ่นเก่าโดยใช้วิธีการอื่น ๆ ที่กล่าวถึงข้างต้น


1

ฉันใช้ curl ใน PHP เพื่อหลีกเลี่ยงสิ่งนี้ ฉันมี webservice ที่ทำงานในพอร์ต 82

<?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;

?>

นี่คือจาวาสคริปต์ที่ทำให้การเรียกไฟล์ PHP

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 ของฉันทำงานบน WAMP ในพอร์ต 80 ดังนั้นเราจึงไปนโยบายต้นกำเนิดเดียวกันถูกหลีกเลี่ยง :-)



1

วิเคราะห์สิ่งที่มีอยู่ในนี้: http://www.slideshare.net/SlexAxton/breaking-the-cross-domain-barrier

สำหรับโซลูชัน postMessage ลองดูที่:

https://github.com/chrissrogers/jquery-postmessage/blob/master/jquery.ba-postmessage.js

และรุ่นที่แตกต่างกันเล็กน้อย:

https://github.com/thomassturm/ender-postmessage/blob/master/ender-postmessage.js

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.