web-dev-qa-db-ja.com

同一生成元ポリシーが適用されるかどうかを確認します

実際にajaxメソッドを使用する前に、同じOriginポリシーがURLに適用されるかどうかを確認する「安全な」方法はありますか?これが私が持っているものです:

function testSameOrigin(url) {

    var loc = window.location,
        a = document.createElement('a');

    a.href = url;

    return a.hostname == loc.hostname &&
           a.port == loc.port &&
           a.protocol == loc.protocol;
}

この種の作業は機能しますが、 ウィキペディアの記事 に基づいた手動の推測のようなものです。クロスドメイン許容量を事前にチェックするより良い方法はありますか? jQueryは使用しても問題ありません。

24
David Hellsing

興味深い質問です!調べてみたところ、投稿したもの以外は見つかりませんでしたが、テストコードをいじっていたときに出くわしました。リクエストを行わずにURLをテストする簡単な方法が必要な場合は、私が行っている方法で行います。テストのリクエストを気にしない場合は、次のことを試してみてください。

必要なURLに簡単なajaxリクエストを作成します。

_var ajaxRequest = $.ajax({
  url: 'http://www.google.com',
  async: false
});
_

これはjqXHRオブジェクトを返し、それを確認できます。

_ajaxRequest.isRejected(); // or...
ajaxRequest.isResolved();
_

さて、これに関する唯一の問題は、ページがロードされない(つまり、404 Not Foundなど)すべてのケースでisRejected()trueと評価されることですが、確認することができますステータスコード:

_ajaxRequest.status;
_

同一生成元ポリシーを破ろうとすると、上記の行は_0_を返すように見えますが、それ以外の場合は適切なエラーコード(つまり404)を返します。

まとめると、次のようなことを試してみることができます。

_function testSameOrigin(testUrl) {

  var ajaxRequest = $.ajax({
    url: testUrl,
    async: false
  });

  return ajaxRequest.isRejected() && ajaxRequest.status === 0;
}
_

決して決定的な答えではありませんが、それがあなたが探しているものを理解するのに役立つことを願っています!

8
Steve

実際にajaxメソッドを使用する前に、同じOriginポリシーがURLに適用されるかどうかを確認する「安全な」方法はありますか?これが私が持っているものです:

function testSameOrigin(url) {

    var loc = window.location,
        a = document.createElement('a');

    a.href = url;

    return a.hostname == loc.hostname &&
           a.port == loc.port &&
           a.protocol == loc.protocol;
}

これは、特定のことを実行している(または実行していない)場合に限り、安全で信頼性の高い方法です。

この種の作業は機能しますが、ウィキペディアの記事に基づいた手動の推測のようなものです。

これは、「通常の」状況で完全に機能するはずです。 クロスドメインスクリプティング を使用する場合は、変更する必要があります。

スクリプトでdocument.domainを変更すると、たとえば「foo.example.com」や「bar.example.com」から「example.com」に変更すると、testSameOrigin関数はfalse for " http://example.com "、実際にはtrueを返す必要があります。

document.domainの変更を計画している場合は、スクリプトにそのチェックを追加するだけで追加できます。

CORS(上記のリンクを参照)を使用してクロスドメイン通信を許可することを計画している場合は、フォールスネガティブも返します。ただし、CORSを使用している場合は、通信できるドメインのリストがあり、そのリストをこの関数に追加することもできます。

クロスドメイン許容量を事前にチェックするより良い方法はありますか? jQueryは使用しても問題ありません。

おそらくそうではありませんが、スティーブの答えからコンソールに表示されているのは「オブザーバーのジレンマ」である可能性があることを言及する価値があるかもしれません...これらのエラーは、コンソールが他のウィンドウを検査しようとしたためであるように見えますが、必ずしもスクリプト。

document.domainをいじったり、CORSを使用したりしていないと仮定すると、サーバーが使用可能かどうかを判断するために追加のリクエストを行う必要がないため、元のソリューションの方がおそらく優れています。クロスドメインスクリプティングを行っている場合でも、それに対応するために現在持っている関数を変更するのがおそらく最善の策です。

15
Dagg Nabbit

このソリューションも試してください。

function csrfSafeMethod(method) {
  // these HTTP methods do not require CSRF protection
  return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

function sameOrigin(url) {
  // test that a given url is a same-Origin URL
  // url could be relative or scheme relative or absolute
  var Host = window.document.location.Host; // Host + port
  var protocol = window.document.location.protocol;
  var srOrigin = '//' + Host;
  var Origin = protocol + srOrigin;
  // Allow absolute or scheme relative URLs to same Origin
  return (url === Origin || url.slice(0, Origin.length + 1) === Origin + '/') ||
    (url === srOrigin || url.slice(0, srOrigin.length + 1) === srOrigin + '/') ||
    // or any other URL that isn't scheme relative or absolute i.e relative.
    !(/^(\/\/|http:|https:).*/.test(url));
}

// if you want to check before you make a call
if (!csrfSafeMethod(data.type) && sameOrigin(data.url)) {
  // ...
}

// or if you want to set csrf token
$.ajax({
  beforeSend: function (xhr, settings) {
    if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
      xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
    }
  }
});
2
jo_asakura

Dagg Nabbitの答えに基づいて、これはもう少し完全に思えます。

function sameOrigin(url) {
    var loc = window.location, a = document.createElement('a')
    a.href = url

    return a.hostname === loc.hostname &&
           a.port === loc.port &&
           a.protocol === loc.protocol &&
           loc.protocol !== 'file:'
}

私が考えることができる警告:

0
B T

クロスドメインスクリプトを実行する別の方法は、 JSON-P を使用することです。これも読むことができます 記事 。それ以外の場合、クロスドメインスクリプティングは同一生成元ポリシーで許可されません。

0
Alberto De Caro