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


150

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

Я хотів зробити вікі спільноти щодо політики однозначного походження HTML / JS, щоб сподіватися допомогти всім, хто шукає цю тему. Це одна з найбільш шуканих тем на SO, і для неї немає консолідованої вікі, тож ось я іду :)

Та ж політика оригіналу не дозволяє документу або сценарію, завантаженому з одного джерела, отримувати або встановлювати властивості документа з іншого джерела. Ця політика бере початок ще до Netscape Navigator 2.0.

Які є ваші улюблені способи обійти політику з однаковим походженням?

Будь ласка, зберігайте приклади багатослівно та бажано також зв’язати свої джерела.


4
приємна ідея .. Хоча слід поставити свої приклади у відповідь (а); на сьогоднішній день, вони ставлять питання досить об'ємним
Shog9

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

Чому близько? Це (вікі) питання було досить корисним протягом останніх 2 років. Крім того, багато відповідей на які підтримуються посилання. Пояснення було б вдячно, оскільки not constructiveтег здається абсолютно неприйнятним. Проголосували за повторне відкриття.
Девід Тітаренко

Відповіді:


84

document.domainметод

  • Тип способу: рамка .

Зауважте, що це метод 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.

За допомогою цього методу вам буде дозволено виконувати 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.

Команда 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метод

  • Тип способу: рамка .

window.postMessage, при виклику викликає MessageEventрозсилку в цільове вікно, коли будь-який очікуваний сценарій, який повинен бути виконаний, завершується (наприклад, залишилися обробники подій, якщо 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?
Айяш

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, в той час як сервер буде виконувати роль проксі-сервера до будь-якого віддаленого місця.

Якщо ви використовуєте 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). Тож вам дійсно доведеться довіряти їм, що вони не роблять поганих речей і не стають зламаними.
Ерленд

1
@Erlend: Будь-яку інформацію, що подається в Інтернеті, може отримати будь-хто (якщо не потрібна належна автентифікація). Точний формат подання цієї інформації не робить це кращим чи гіршим, навіть якщо це JSONP.
T-Bull

2
@ T-Bull: Проблема полягає в тому, що правильна автентифікація неможлива за допомогою JSONP. Користувач входить на сайт A, а потім переходить на сайт B, який завантажує дані з A за допомогою тега сценарію JSONP. Як і добре. Потім користувач підманює відвідувати злий сайт C, який також використовує тег сценарію JSONP для завантаження даних з А. Отже, оскільки користувач має автентифікацію на A, власник C тепер може викрасти дані користувачів у А. І це навіть якщо користувач використовував двофакторну автентифікацію для автентифікації з А. Проблема полягає в тому, що JSONP дуже небезпечний. І JSONP - це не презентація. Це небезпечна передача даних.
Ерленд

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 / дані, незалежно від їх походження. Іншими словами, це робить будь-який 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 зможе прочитати всі ваші дані, передані через b) anyorigin може XSS перетворити ваш сайт, прочитати всі ваші дані на вашому сайті та доставити зловмисне програмне забезпечення вашим користувачам (що станеться, якщо anyorigin зламаний?)
Ерленд

@Erlend - роздвойте Whateverorigin і розмістіть його на власному сервері. Код є тривіальним, тому ви можете переглянути його, щоб переконатися, що там не ховаються подвиги.
ripper234


3

На думку JSONP :

JSONP або "JSON з прокладкою" - це доповнення до базового формату даних JSON, схеми використання, яка дозволяє сторінці запитувати та більш значущо використовувати JSON з іншого сервера, ніж основний сервер. JSONP - це альтернатива більш новітньому методу, який називається перехресним розподілом ресурсів.


Дивіться мій коментар до JSONP вище. Не вдалий вибір для приватних даних.
Ерленд

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

Щоб отримати рішення після процедури, зверніть увагу на:

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.