Các cách để phá vỡ chính sách cùng nguồn gốc


150

Chính sách xuất xứ tương tự

Tôi muốn tạo một wiki cộng đồng về các chính sách cùng nguồn gốc HTML / JS để hy vọng giúp đỡ bất cứ ai tìm kiếm chủ đề này. Đây là một trong những chủ đề được tìm kiếm nhiều nhất trên SO và không có wiki tổng hợp nào cho nó vì vậy tôi đi đây :)

Chính sách nguồn gốc tương tự ngăn tài liệu hoặc tập lệnh được tải từ một nguồn gốc khỏi nhận hoặc đặt thuộc tính của tài liệu từ nguồn gốc khác. Chính sách này bắt đầu từ Netscape Navigator 2.0.

Một số cách yêu thích của bạn để đi xung quanh các chính sách cùng nguồn gốc là gì?

Vui lòng giữ các ví dụ dài dòng và tốt nhất là liên kết các nguồn của bạn.


4
ý tưởng hay .. Bạn nên đặt ví dụ của bạn vào câu trả lời mặc dù; khi nó đứng, họ làm cho câu hỏi khá cồng kềnh
Shog9

1
Bạn cũng nên thêm một danh sách các ý nghĩa bảo mật cho mỗi phương pháp. JSONP rất không an toàn cho dữ liệu riêng tư.
Erlend

Tại sao lại gần? Câu hỏi (wiki) này khá hữu ích trong 2 năm qua. Hơn nữa, nhiều câu trả lời được hỗ trợ bởi các tài liệu tham khảo. Một lời giải thích sẽ được đánh giá cao vì một not constructivethẻ dường như hoàn toàn điên rồ. Bình chọn để mở lại.
David Titarenco

Câu trả lời:


84

các document.domainphương pháp

  • Kiểu phương thức: iframe .

Lưu ý rằng đây là phương thức iframe đặt giá trị của document.domain thành hậu tố của tên miền hiện tại. Nếu đúng như vậy, tên miền ngắn hơn được sử dụng cho các lần kiểm tra gốc khác. Ví dụ: giả sử tập lệnh trong tài liệu http://store.company.com/dir/other.htmlthực thi câu lệnh sau:

document.domain = "company.com";

Sau khi câu lệnh đó được thực thi, trang sẽ vượt qua kiểm tra gốc http://company.com/dir/page.html. Tuy nhiên, với lý do tương tự, company.com không thể đặt document.domain thành othercompany.com.

Với phương pháp này, bạn sẽ được phép thoát javascript từ iframe có nguồn gốc trên một tên miền phụ trên một trang có nguồn gốc trên tên miền chính. Phương pháp này không phù hợp với tài nguyên tên miền chéo vì các trình duyệt như Firefox sẽ không cho phép bạn thay đổi document.domaintên miền hoàn toàn xa lạ.

Nguồn: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript

Phương pháp chia sẻ tài nguyên chéo

  • Loại phương thức: AJAX .

Chia sẻ tài nguyên nguồn gốc chéo (CORS) là Dự thảo hoạt động của W3C xác định cách trình duyệt và máy chủ phải giao tiếp khi truy cập các nguồn qua nguồn gốc. Ý tưởng cơ bản đằng sau CORS là sử dụng các tiêu đề HTTP tùy chỉnh để cho phép cả trình duyệt và máy chủ biết đủ về nhau để xác định xem yêu cầu hoặc phản hồi nên thành công hay thất bại.

Đối với một yêu cầu đơn giản, một yêu cầu sử dụng một GEThoặc POSTkhông có tiêu đề tùy chỉnh và cơ thể của ai text/plain, yêu cầu được gửi với một tiêu đề bổ sung được gọi Origin. Tiêu đề Origin chứa nguồn gốc (giao thức, tên miền và cổng) của trang yêu cầu để máy chủ có thể dễ dàng xác định liệu nó có nên phục vụ phản hồi hay không. Một Origintiêu đề ví dụ có thể trông như thế này:

Origin: http://www.stackoverflow.com

Nếu máy chủ quyết định rằng yêu cầu nên được cho phép, nó sẽ gửi một Access-Control-Allow-Origintiêu đề lặp lại cùng một nguồn gốc đã được gửi hoặc *nếu đó là một tài nguyên công cộng. Ví dụ:

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

Nếu tiêu đề này bị thiếu hoặc nguồn gốc không khớp, thì trình duyệt sẽ không cho phép yêu cầu. Nếu tất cả đều ổn, thì trình duyệt sẽ xử lý yêu cầu. Lưu ý rằng cả yêu cầu và phản hồi đều không bao gồm thông tin cookie.

Nhóm Mozilla gợi ý trong bài đăng của họ về CORS rằng bạn nên kiểm tra sự tồn tại của withCredentials tài sản để xác định xem trình duyệt có hỗ trợ CORS thông qua XHR không. Sau đó, bạn có thể kết hợp với sự tồn tại của XDomainRequestđối tượng để bao trùm tất cả các trình duyệt:

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();
}

Lưu ý rằng để phương thức CORS hoạt động, bạn cần có quyền truy cập vào bất kỳ loại cơ chế tiêu đề máy chủ nào và không thể truy cập bất kỳ tài nguyên của bên thứ ba nào.

Nguồn: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-shishing/

các window.postMessagephương pháp

  • Kiểu phương thức: iframe .

window.postMessage, khi được gọi, sẽ khiến một MessageEventlệnh được gửi ở cửa sổ đích khi bất kỳ tập lệnh đang chờ xử lý nào phải được thực thi hoàn thành (ví dụ: các trình xử lý sự kiện còn lại nếu window.postMessageđược gọi từ một trình xử lý sự kiện, thời gian chờ được đặt trước đó, v.v.). Thông báo MessageEventcó loại thông báo, thuộc datatính được đặt thành giá trị chuỗi của đối số đầu tiên được cung cấp cho window.postMessage, thuộc origintính tương ứng với nguồn gốc của tài liệu chính trong cửa sổ gọi window.postMessagevào thời điểm đó window.postMessagevà thuộc sourcetính là cửa sổ từ đó window.postMessageđược gọi.

Để sử dụng window.postMessage, một trình lắng nghe sự kiện phải được đính kèm:

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

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

Và một receiveMessagehàm phải được khai báo:

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

Iframe ngoài trang web cũng phải gửi các sự kiện đúng cách thông qua postMessage:

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

Bất kỳ cửa sổ nào cũng có thể truy cập phương thức này trên bất kỳ cửa sổ nào khác, bất cứ lúc nào, bất kể vị trí của tài liệu trong cửa sổ, để gửi tin nhắn. Do đó, bất kỳ người nghe sự kiện nào được sử dụng để nhận tin nhắn trước tiên phải kiểm tra danh tính của người gửi tin nhắn, bằng cách sử dụng các thuộc tính nguồn gốc và có thể là nguồn. Điều này không thể được nhấn mạnh: Không kiểm tra các thuộc tính originvà có thể sourcecho phép các cuộc tấn công kịch bản chéo trang.

Nguồn: https://developer.mozilla.org/en/DOM/window.postMessage



Tôi hy vọng tôi không quá muộn để nhận được câu trả lời: bởi câu hỏi duy nhất là, localhost LUÔN là một ngoại lệ? nó luôn luôn không được phép? Tôi có nên dừng thử nghiệm thông qua localhost của mình không?
Ayyash

1
Tôi không chắc tại sao nhưng khi tôi đặt: Access-Control-Allow-Origin: http://www.stackoverflow.com/thay vì: Access-Control-Allow-Origin: http://www.stackoverflow.com(gạch chéo ở cuối url), nó không hoạt động trong Safari và FF mà hoạt động trong Chrome. Tất nhiên không có dấu gạch chéo hoạt động tốt trong tất cả các trình duyệt.
mtfk

1
Có thể đáng để mọi người biết rằng postMessagephương pháp này chỉ hoạt động đối với các trình duyệt hỗ trợ nó, vì nó là một bổ sung HTML5. Plugin này cố gắng giải thích cho điều đó. Chỉ cần đề cập đến nó bởi vì tôi đang học điều này một cách khó khăn.
IronicMuffin

41

Phương thức Proxy ngược

  • Kiểu phương thức: Ajax

Thiết lập proxy ngược đơn giản trên máy chủ, sẽ cho phép trình duyệt sử dụng các đường dẫn tương đối cho các yêu cầu Ajax, trong khi máy chủ sẽ hoạt động như một proxy cho bất kỳ vị trí từ xa nào.

Nếu sử dụng mod_proxy trong Apache, chỉ thị cấu hình cơ bản để thiết lập proxy ngược là ProxyPass. Nó thường được sử dụng như sau:

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

Trong trường hợp này, trình duyệt sẽ có thể yêu cầu /ajax/web_service.xmlnhư một URL tương đối, nhưng máy chủ sẽ phục vụ điều này bằng cách hoạt động như một proxy http://other-domain.com/ajax/web_service.xml.

Một tính năng thú vị của phương pháp này là proxy ngược có thể dễ dàng phân phối các yêu cầu tới nhiều back-end, do đó hoạt động như một bộ cân bằng tải .


17

Tôi sử dụng JSONP.

Về cơ bản, bạn thêm

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

trên trang của bạn.

some_func () sẽ được gọi để bạn được thông báo rằng dữ liệu đang ở trong.


7
JSONP có hai vấn đề: a) Bạn đang thêm thẻ script vào miền đích. Họ có thể gửi lại bất cứ thứ gì, thậm chí là javascript thông thường (tấn công XSS). Vì vậy, bạn thực sự phải tin tưởng họ không làm điều xấu hoặc bị hack b) Bất kỳ trang web nào khác cũng có thể thêm cùng một thẻ script và đánh cắp dữ liệu, vì vậy đừng bao giờ sử dụng JSONP cho dữ liệu riêng tư.
Erlend

1
@Erlend: Bất kỳ thông tin nào được cung cấp trên web đều có thể được lấy bởi bất kỳ ai (trừ khi cần phải xác thực đúng cách). Định dạng chính xác về cách thông tin được trình bày không làm cho điều này tốt hơn hoặc tồi tệ hơn, ngay cả khi đó là JSONP.
T-Bull

2
@ T-Bull: Vấn đề là không thể xác thực đúng cách với JSONP. Một người dùng đăng nhập vào trang A và sau đó đến trang B, nơi tải dữ liệu từ A bằng thẻ script JSONP. Như là tốt và tốt. Sau đó, người dùng bị lừa truy cập trang web ác C, cũng sử dụng thẻ script JSONP để tải dữ liệu từ A. Vì vậy, vì người dùng được xác thực bằng A, chủ sở hữu của C giờ có thể đánh cắp dữ liệu của người dùng từ A. Và đó là ngay cả khi người dùng đã sử dụng xác thực hai yếu tố để xác thực bằng A. Vấn đề là JSONP rất không an toàn. Và JSONP không phải là bản trình bày. Đó là truyền dữ liệu không an toàn.
Erlend

1
JSONP chỉ hỗ trợ HTTP GET.
opyate

Tệp .js này đại diện cho điều gì -> "http: //..../someData.js.... Tôi đang cố đọc dom từ phía khách hàng của trang web khác và cần phá vỡ chính sách cùng nguồn gốc .
CS_2013

13

AnyOrigin không hoạt động tốt với một số các trang web https, vì vậy tôi chỉ viết một cách thay thế nguồn mở được gọi là whateverorigin.org điều đó dường như làm việc tốt với https.

Mã trên github .


@DavidTitarenco - nó làm tôi phát điên khi cố gắng hiểu một số điều đang diễn ra trong bụng của anyorigin. May mắn thay, tôi đã tìm thấy một bài đăng trên blog có ích, và bây giờ anh chàng tiếp theo sẽ có một trang web thử nghiệm làm việc nếu anh ta cần.
ripper234

@neoascetic - Đã sửa lỗi sử dụng ... URL cần được mã hóa ngay bây giờ.
ripper234

12

Cách gần đây nhất để khắc phục chính sách cùng nguồn gốc mà tôi đã tìm thấy là http://anyorigin.com/

Trang web được tạo để bạn chỉ cần cung cấp cho nó bất kỳ url nào và nó tạo mã javascript / jquery cho bạn, cho phép bạn lấy html / dữ liệu, bất kể nguồn gốc của nó là gì. Nói cách khác, nó làm cho bất kỳ url hoặc trang web nào trở thành một yêu cầu JSONP.

Tôi thấy nó khá hữu ích :)

Dưới đây là một số ví dụ mã javascript từ anyorigin:

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

Mặc dù nó mang lại cho tôi một số vấn đề với các trang web https, vì vậy hãy xem thay thế nguồn mở của tôi bên dưới: stackoverflow.com/questions/3076414/
ám

13
Điều đó có nghĩa là: a) anyorigin sẽ có thể đọc tất cả dữ liệu của bạn được truyền qua tem b) anyorigin có thể XSS trang web của bạn, đọc tất cả dữ liệu của bạn trên trang web của bạn và cung cấp phần mềm độc hại cho người dùng của bạn (điều gì xảy ra nếu anyorigin bị hack?)
Erlend

@Erlend - fork Anyorigin và lưu trữ nó trên máy chủ của riêng bạn. Mã này là tầm thường để bạn có thể xem lại nó để đảm bảo không có khai thác nào được ẩn ở đó.
ripper234


3

Các JSONP nói đến cái tâm:

JSONP hoặc "JSON with padding" là phần bổ sung cho định dạng dữ liệu JSON cơ bản, một kiểu sử dụng cho phép một trang yêu cầu và sử dụng JSON một cách có ý nghĩa hơn từ một máy chủ khác ngoài máy chủ chính. JSONP là một phương pháp thay thế cho một phương pháp gần đây hơn được gọi là Chia sẻ tài nguyên nguồn gốc chéo.


Xem bình luận của tôi cho JSONP ở trên. Không phải là một lựa chọn tốt cho dữ liệu riêng tư.
Erlend

1

Cá nhân, window.postMessagelà cách đáng tin cậy nhất mà tôi đã tìm thấy cho các trình duyệt hiện đại. Bạn phải làm thêm một chút công việc để đảm bảo rằng bạn không để mình bị mở cho các cuộc tấn công XSS, nhưng đó là một sự đánh đổi hợp lý.

Ngoài ra còn có một số bổ trợ cho các bộ công cụ Javascript phổ biến hiện có gói window.postMessagecung cấp chức năng tương tự cho các trình duyệt cũ hơn bằng các phương pháp khác được thảo luận ở trên.


1

Chà, tôi đã sử dụng curl trong PHP để phá vỡ điều này. Tôi có một dịch vụ web đang chạy ở cổng 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;

?>

Đây là javascript thực hiện cuộc gọi đến tệp 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 của tôi chạy trên WAMP trong cổng 80. Vì vậy, chúng tôi đi, chính sách xuất xứ tương tự đã bị phá vỡ :-)



Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.