Access-Control-Allow-Originをバイパスする方法


197

私は自分のサーバーにajax呼び出しを行って、これらのajax呼び出しを防止するように設定したプラットフォームでサーバーにデータをフェッチして、サーバーのデータベースから取得したデータを表示する必要があります。私のajaxスクリプトは機能しています。サーバーのphpスクリプトにデータを送信して、処理できるようにすることができます。ただし、処理されたデータは、"Access-Control-Allow-Origin"

そのプラットフォームのソース/コアにアクセスできません。そのため、許可されていないスクリプトは削除できません。(P / SIはGoogle Chromeのコンソールを使用し、このエラーを発見しました)

以下に示すAjaxコード:

 $.ajax({
     type: "GET",
     url: "http://example.com/retrieve.php",
     data: "id=" + id + "&url=" + url,
     dataType: 'json',   
     cache: false,
     success: function(data)
      {
        var friend = data[1];              
        var blog = data[2];           
        $('#user').html("<b>Friends: </b>"+friend+"<b><br> Blogs: </b>"+blog);

      } 
  });

またはJSON上記のajaxスクリプトに相当するコードはありますか?JSON許されると思います。

誰かが私を助けてくれることを願っています。


これまでの質問に対するすべての回答は、サーバーコードを書き直してajaxが機能するようにする方法を説明していました。あなたが質問で具体的に尋ねたように、それらのいずれもバイパスに関するものではありません。とにかく、このヘッダーを実際にバイパスする方法を見つけましたか?本当にあるとは思えません。
Moradnejad 2017

それをベイパスする方法はありません。ただし、リクエストを実行するファイルをバックエンドに置くことができます。したがって、あなたは自分のサーバー上のファイルをajaxごとに呼び出し、そのファイルはretrieve.phpからデータをロードし、それらをJavaScriptに送り返します。その場合、あなたをブロックするCORSルールはありません。
Jona Paulus

回答:


367

これをretrieve.phpの上に置きます。

header('Access-Control-Allow-Origin: *');  

これにより、効果的にCORS保護が無効になり、ユーザーが攻撃にさらされることに注意してください。すべてのオリジンを許可する必要があるかどうか完全に確信していない場合は、これをより具体的なオリジンにロックする必要があります。

header('Access-Control-Allow-Origin: https://www.example.com')

の理解を深めるには、次のスタック回答を参照してください Access-Control-Allow-Origin

https://stackoverflow.com/a/10636765/413670


54
それはかなり安全ではありません。一番下の私の答えをチェックしてください。
Rob

3
tnx、しかし彼のコメントで@RobQuistによって言及されたようにすべてのオリジンへのアクセスを許可すべきではありません、そして彼の答えでより良いアプローチを提供しました
Rafay

2
サーバーでアクセス制御を実際に「バイパス」する必要があったため、このページを見つけました。ここでの解決策は何もバイパスせず、自分のサーバーでAccess Controlを適切に構成するだけです。実際にこれをバイパスする必要がある場合は、PHPのfile_get_contents($ remote_url);を使用できます。これを行うには明らかに多くの方法がありますが、これは私がやった方法です。
Shawn Whinnery 2014年

1
@ShawnWhinneryは基本的に「プロキシ」の行為です。自分が制御できない別のWebサイトからデータを動的にロードする場合は、優れたソリューションです。
Rob

1
dotnetコアからPHPスクリプトを実行したい-phpスクリプトを他のURLに移動したが、クロスサイトスクリプティングエラーが発生した。あなたが示したコードをPHPの上に追加し、完全に動作しました。ありがとう!
raddevus

291

わかりましたが、*はワイルドカードであり、すべてのドメインからのクロスサイトスクリプティングが可能であることをご存じでしょうか。

Access-Control-Allow-Origin許可されているすべてのサイトに複数のヘッダーを送信したいのですが、残念ながら、複数のAccess-Control-Allow-Originヘッダーを送信したり、複数のオリジンを配置したりすることは公式にサポートされていません。

これを解決するには、オリジンを確認し、許可されている場合はヘッダーでオリジンを送り返します。

$origin = $_SERVER['HTTP_ORIGIN'];
$allowed_domains = [
    'http://mysite1.com',
    'https://www.mysite2.com',
    'http://www.mysite2.com',
];

if (in_array($origin, $allowed_domains)) {
    header('Access-Control-Allow-Origin: ' . $origin);
}

それははるかに安全です。マッチングを編集して、正規表現などを使用した手動関数に変更したい場合があります。少なくとも、これは1つのヘッダーのみを送信し、要求の送信元のヘッダーであることが確実になります。すべてのHTTPヘッダー偽装される可能性がありますが、このヘッダーはクライアントを保護するためのものであることに注意してください。これらの値で自分のデータを保護しないでください。詳細を知りたい場合は、CORSとCSRFを少し読んでください。

なぜ安全なのですか?

他の場所からのアクセスを許可すると、独自の信頼できるサイトでセッションのハイジャックが可能になります。少し例を挙げましょう。画像Facebookではワイルドカードを使用できます。つまり、独自のWebサイトをどこかに作成し、Facebookに対してAJAX呼び出し(またはiframeを開く)を起動させることができます。これはあなたがあなたのウェブサイトの訪問者のFacebookのログイン情報をつかむことができることを意味します。さらに悪いことには、POSTリクエストをスクリプト化して、誰かのFacebookにデータを投稿することができます。

ACAOヘッダーを使用するときは注意が必要です。


12
リストの各項目の前にhttp://を付ける必要があると思います。少なくとも、私が取り組んでいた1つのサイトに対してしました。
blak3r 2013年

2
残念ながら、これはうまくいかないようです。header()の呼び出しごとに提供できる例外は1つだけだと思います。
lewsid 2013年

5
@Shanimal&lewsid->カンマ区切りは実際には機能しないと思います。参照:w3.org/TR/cors
Rob

3
ドメインのリストを処理するための、ここでの関連する回答:stackoverflow.com/a/1850482/766177
Valentin Despa

13
への呼び出しごとheader()に同じタイプの以前のヘッダーが置き換えられるため、このように4つのヘッダーを追加しても意味がありません。つまり、実際に行っているのは最後のヘッダーを設定することだけです。手入力での2番目のパラメータを設定できることを述べてfalse、前のヘッダは上書きされるのを防ぐために。
BadHorsie 2016年

31

警告、Chrome(およびその他のブラウザ)は、他の回答のいずれかを実行すると、複数のACAOヘッダーが設定されると文句を言います。

エラーは次のようなものになります XMLHttpRequest cannot load ____. The 'Access-Control-Allow-Origin' header contains multiple values '____, ____, ____', but only one is allowed. Origin '____' is therefore not allowed access.

これを試して:

$http_origin = $_SERVER['HTTP_ORIGIN'];

$allowed_domains = array(
  'http://domain1.com',
  'http://domain2.com',
);

if (in_array($http_origin, $allowed_domains))
{  
    header("Access-Control-Allow-Origin: $http_origin");
}

6
これは私が投稿したものよりも優れたソリューションです。
Rob

7

MVC3コントローラーを呼び出すときにこの問題を修正しました。追加した:

Response.AddHeader("Access-Control-Allow-Origin", "*"); 

私の前に

return Json(model, JsonRequestBehavior.AllowGet);

また、私$.ajaxはajax呼び出しでContent-typeヘッダーを受け入れないと不満を言っていたので、そのJSONがアクションに渡されることを知っているのでコメントアウトしました。

お役に立てば幸いです。


2

を使用するのは非常に悪い考え*です。そのため、クロスサイトスクリプティングの可能性が広がります。基本的に、常に自分のドメインを望み、現在のSSL設定をスコープとし、オプションで追加のドメインを必要とします。また、それらすべてを1つのヘッダーとして送信することもできます。以下は、常に現在のページと同じSSLスコープで独自のドメインを承認し、オプションで任意の数の追加ドメインを含めることもできます。すべてが1つのヘッダーとして送信され、他の何かがすでに送信した場合は、以前のヘッダーが上書きされ、ブラウザーが複数のアクセス制御ヘッダーが送信されることについて不平を言う可能性を回避します。

class CorsAccessControl
{
    private $allowed = array();

    /**
     * Always adds your own domain with the current ssl settings.
     */
    public function __construct()
    {
        // Add your own domain, with respect to the current SSL settings.
        $this->allowed[] = 'http'
            . ( ( array_key_exists( 'HTTPS', $_SERVER )
                && $_SERVER['HTTPS'] 
                && strtolower( $_SERVER['HTTPS'] ) !== 'off' ) 
                    ? 's' 
                    : null )
            . '://' . $_SERVER['HTTP_HOST'];
    }

    /**
     * Optionally add additional domains. Each is only added one time.
     */
    public function add($domain)
    {
        if ( !in_array( $domain, $this->allowed )
        {
            $this->allowed[] = $domain;
        }
    /**
     * Send 'em all as one header so no browsers grumble about it.
     */
    public function send()
    {
        $domains = implode( ', ', $this->allowed );
        header( 'Access-Control-Allow-Origin: ' . $domains, true ); // We want to send them all as one shot, so replace should be true here.
    }
}

使用法:

$cors = new CorsAccessControl();

// If you are only authorizing your own domain:
$cors->send();

// If you are authorizing multiple domains:
foreach ($domains as $domain)
{
    $cors->add($domain);
}
$cors->send();

あなたはアイデアを得ます。


1

サーバーから送信された応答に実際にAccess-Control-Allow-Originヘッダーを追加してみましたか?のようにAccess-Control-Allow-Origin: *


1
スクリプトの元のドメインがサーバーのドメインと一致しないにもかかわらず、呼び出し元のスクリプトに結果を公開してもよいことをブラウザーに通知するためにサーバーが送信するHTTPヘッダーです。Cross-Origin Resource Sharingについて読んでください!
Daniel Brockman、2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.