Способы обхода политики одного и того же происхождения

То же правило происхождения

Я хотел бы сделать wiki сообщества относительно HTML/JS политик одинакового происхождения, чтобы, надеюсь, помочь любому, кто ищет эту тему. Это одна из самых популярных тем для SO, и для нее нет консолидированной вики, поэтому я иду:)

Такая же политика происхождения предотвращает документ или script, загруженный из одного происхождение от получения или установки свойства документа от другого происхождение. Эта политика датируется полностью вернуться к Netscape Navigator 2.0.

Каковы некоторые из ваших любимых способов обойти политики одинакового происхождения?

Пожалуйста, держите примеры подробными и желательно также связывать свои источники.

Ответ 1

Метод document.domain

  • Тип метода: iframe.

Обратите внимание, что это метод iframe, который устанавливает значение document.domain в суффикс текущего домена. Если это так, более короткий домен используется для последующих проверок происхождения. Например, предположим, что script в документе в http://store.company.com/dir/other.html выполняет следующее утверждение:

document.domain = "company.com";

После выполнения этого утверждения страница проведет проверку происхождения с помощью http://company.com/dir/page.html. Однако по тем же соображениям company.com не может установить document.domain в othercompany.com.

С помощью этого метода вам будет разрешено вызывать javascript из iframe, полученного на субдомене на странице, полученной в основном домене. Этот метод не подходит для междоменных ресурсов, поскольку такие браузеры, как Firefox, не позволят вам изменить document.domain на полностью чуждый домен.

Источник: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript

Метод совместного использования ресурсов Cross-Origin

  • Тип метода: AJAX.

Совместное использование ресурсов для разных источников (CORS) - это рабочий проект W3C, который определяет, как браузер и сервер должны взаимодействовать при доступе к источникам через источник, Основная идея 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

Если этот заголовок отсутствует или исходное имя не совпадает, браузер не разрешает запрос. Если все хорошо, браузер обрабатывает запрос. Обратите внимание, что ни запросы, ни ответы не содержат информацию о файлах cookie.

Команда 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 при вызове вызывает отправку MessageEvent в целевом окне, когда все ожидающие завершения функции script завершаются (например, оставшиеся обработчики событий, если window.postMessage вызывается из обработчика события, ранее -set ожидания ожидания и т.д.). MessageEvent имеет сообщение типа, свойство data, которое устанавливается в строковое значение первого аргумента, предоставленного в window.postMessage, свойство Origin, соответствующее началу основного документа в окне, вызывающем window.postMessage в момент времени window.postMessage и свойство source, которое является окном, из которого вызывается window.postMessage.

Чтобы использовать window.postMessage, необходимо подключить прослушиватель событий:

    // 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

Ответ 2

Метод обратного прокси

  • Тип метода: 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.

Одна интересная особенность этого метода заключается в том, что обратный прокси-сервер может легко распространять запросы на несколько обратных контентов, действуя как балансировка нагрузки.

Ответ 3

Я использую JSONP.

В принципе, вы добавляете

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

на вашей странице.

some_func() следует вызвать, чтобы вы получили уведомление о том, что данные находятся.

Ответ 4

AnyOrigin не работал с некоторыми сайтами https, поэтому я просто написал альтернативу с открытым исходным кодом, называемую whateverorigin.org, которая, кажется, хорошо работает с https.

Код в github.

Ответ 5

Самый последний способ преодоления той же политики, что и я, - http://anyorigin.com/

Сайт создан так, что вы просто даете ему какой-либо url, и он генерирует код javascript/jquery для вас, который позволяет вам получить html/data, независимо от его происхождения. Другими словами, он делает любой URL-адрес или веб-страницу запросом JSONP.

Я нашел его довольно полезным:)

Вот пример javascript-кода от anyorigin:

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

Ответ 6

Я не могу претендовать на кредит для этого изображения, но он соответствует всему, что я знаю по этому вопросу, и предлагает немного юмора в то же время.

http://www.flickr.com/photos/iluvrhinestones/5889370258/

Ответ 7

На ум приходит JSONP:

JSONP или "JSON с заполнением" - это дополнение к базовым данным JSON формат, шаблон использования, который позволяет страницу для запроса и более значимо используйте JSON с сервера, отличного от первичный сервер. JSONP - это альтернатива более позднему методу называется совместным использованием ресурсов Cross-Origin.

Ответ 8

Лично window.postMessage - самый надежный способ, который я нашел для современных браузеров. Вам нужно сделать немного больше работы, чтобы убедиться, что вы не оставляете себя открытым для атак XSS, но это разумный компромисс.

Существует также несколько плагинов для популярных инструментов Javascript, которые включают window.postMessage, которые предоставляют аналогичную функциональность старым браузерам, используя другие методы, описанные выше.

Ответ 9

Ну, я использовал curl в PHP, чтобы обойти это. У меня есть веб-служба, работающая на порту 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;

?>

Вот javascript, который вызывает вызов файла 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. Итак, мы идем, одна и та же политика происхождения была обойдена: -)