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


150

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

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

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

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

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


4
хорошая идея .. Вы должны поместить свои примеры в ответ (ы), хотя; в таком виде они делают вопрос довольно громоздким
Shog9

1
Вы также должны добавить список последствий для безопасности для каждого подхода. JSONP крайне небезопасен для личных данных.
Эрленд

Почему закрыли? Этот (вики) вопрос был весьма полезен в течение последних 2 лет. Кроме того, многие ответы на которые поддерживаются ссылки. Объяснение было бы оценено, поскольку not constructiveпризнак кажется совершенно бессмысленным. Проголосовал за повторное открытие.
Дэвид Титаренко

Ответы:


84

document.domainметод

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

Обратите внимание, что это метод iframe, который устанавливает значение document.domain в суффикс текущего домена. Если это так, более короткий домен используется для последующих проверок происхождения. Например, предположим, что скрипт в документе at 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

Метод совместного использования ресурсов из разных источников

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

В своем посте о CORS команда Mozilla предлагает проверить наличие 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отправку a в целевом окне, когда завершается любой ожидающий сценарий, который должен быть выполнен (например, оставшиеся обработчики событий, если он window.postMessageвызывается из обработчика событий, предварительно установленные тайм-ауты ожидания и т. д.). 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



Я надеюсь, что я не слишком поздно, чтобы получить ответ: единственный вопрос, является ли 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

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

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

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


17

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

В основном, вы добавляете

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

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

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


7
У JSONP есть две проблемы: а) Вы добавляете тег сценария в целевой домен. Они могут отправлять что угодно, даже обычный JavaScript (атака 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, поэтому я просто написал альтернативу с открытым исходным кодом whatorigin.org, которая, кажется, хорошо работает с https.

Код на github .


@DavidTitarenco - это сводило меня с ума, пытаясь понять некоторые вещи, происходящие в животе anyorigin. К счастью, я нашел один пост в блоге, который помог, и теперь у следующего парня будет рабочий тестовый сайт, если он когда-нибудь понадобится.
ripper234

@neoascetic - исправлено использование ... URL должен быть закодирован.
ripper234

12

Самый последний способ преодоления той же политики происхождения, которую я нашел, это 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);
});

Хотя это дало мне некоторые проблемы с сайтами https, так что ознакомьтесь с моей альтернативой с открытым исходным кодом ниже: stackoverflow.com/questions/3076414/…
ripper234

13
Это означает, что: a) anyorigin сможет прочитать все ваши данные, переданные через tem b) anyorigin сможет XSS ваш сайт, прочитать все ваши данные на вашем сайте и доставить вредоносное ПО вашим пользователям (что произойдет, если anyorigin взломан?)
Erlend

@Erlend - форк Whitherorigin и разместите его на своем собственном сервере. Код является тривиальным, поэтому вы можете просмотреть его, чтобы убедиться, что там нет скрытых эксплойтов.
ripper234


3

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

JSONP или «JSON with padding» является дополнением к базовому формату данных JSON, шаблону использования, который позволяет странице запрашивать и более осмысленно использовать JSON с сервера, отличного от основного сервера. JSONP является альтернативой более позднему методу, который называется Cross-Origin Resource Sharing.


Смотрите мой комментарий к JSONP выше. Не очень хороший выбор для личных данных.
Erlend

1

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

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


1

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



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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.