30

私は完全にajax駆動型のアプリケーションに取り組んでおり、すべてのリクエストは基本的にメインコントローラーに相当するものを通過します。メインコントローラーは、基本的には次のようになります。

if(strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    fetch($page);
}

これは一般的に、クロスサイトリクエストフォージェリから保護するのに十分ですか?

ページ全体がリクエストごとに更新されない場合、ローテーショントークンを使用するのはかなり不便です。

リクエストごとにグローバルjavascript変数として一意のトークンを渡して更新できると思いますが、どういうわけかそれは不器用で、とにかく本質的に安全ではないようです。

編集-おそらく、ユーザーのUUIDのような静的トークンは、何もないよりも優れているでしょうか?

編集#2-ルークが指摘したように、これは髪を分割する質問かもしれません。私は両方の方法で憶測を読み、古いバージョンのフラッシュがこの種のシェナニガンに悪用可能であるという遠いささやきを聞きました。私はそれについて何も知らないので、これがどのようにCSRFリスクであるかを説明できる人には賞金をかけています。それ以外の場合は、Artefactoに渡します。ありがとう。

4

6 に答える 6

19

十分だと思います。クロスドメインリクエストが許可された場合、攻撃者がJavascriptを使用してCSRFトークンをフェッチし、それを偽造リクエストで使用する可能性があるため、とにかく運命にあります。

静的トークンは良い考えではありません。トークンは、セッションごとに少なくとも1回生成する必要があります。

EDIT2マイクは結局正しくありません、ごめんなさい。リンク先のページをきちんと読んでいませんでした。それは言う:

単純なクロスサイトリクエストは、次のようなものです。[...] HTTPリクエストでカスタムヘッダーを設定しない(X-Modifiedなど)

したがって、を設定した場合X-Requested-With、リクエストはプリフライトである必要があり、クロスサイトリクエストを承認するプリフライトOPTIONSリクエストに応答しない限り、リクエストは通過しません。

編集マイクは正しいです。Firefox3.5の時点で、クロスサイトXMLHttpRequestsが許可されています。したがって、Originヘッダーが存在する場合は、それがサイトと一致するかどうかも確認する必要があります。

if (array_key_exists('HTTP_ORIGIN', $_SERVER)) {
    if (preg_match('#^https?://myserver.com$#', $_SERVER['HTTP_ORIGIN'])
        doStuff();
}
elseif (array_key_exists('HTTP_X_REQUESTED_WITH', $_SERVER) &&
        (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'))
    doStuff(); 
于 2010-07-26T00:07:58.153 に答える
1

これは安全だとは思いません。同一生成元ポリシーは、異なるドメインのドキュメントが異なるドメインから返されたコンテンツにアクセスできないように設計されています。そもそもXSRFの問題が存在するのはこのためです。一般に、XSRFは応答を気にしません。削除アクションなど、特定のタイプのリクエストを実行するために使用されます。最も単純な形式では、これは適切にフォーマットされたimgタグを使用して実行できます。提案されたソリューションは、この最も単純なフォームを防ぎますが、誰かがXMLHttpオブジェクトを使用してリクエストを行うことを保護しません。XSRFの標準的な防止手法を使用する必要があります。javascriptで乱数を生成し、それをCookieとフォーム変数に追加するのが好きです。これにより、コードがそのドメインのCookieも書き込むことができるようになります。詳細については、をご覧ください。このエントリ

また、スクリプトで機能していないXMLHttpに関するコメントを横取りします。Firefox 3.5で次のコードを使用して、ローカルホストドメインで実行されているhtmlからgoogleにリクエストを送信しました。コンテンツは返されませんが、firebugを使用すると、リクエストが行われたことがわかります。

<script>
var xmlhttp = false; 

if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
    try {
        xmlhttp = new XMLHttpRequest();
    } catch (e) {
        xmlhttp = false;
    }
}
if (!xmlhttp && window.createRequest) {
    try {
        xmlhttp = window.createRequest();
    } catch (e) {
        xmlhttp = false;
    }
}

xmlhttp.open("GET", "http://www.google.com", true);
xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4) {
        alert("Got Response");
        alert(xmlhttp.responseText)
    }
}

xmlhttp.send(null)
alert("test Complete");

于 2010-07-27T15:42:23.497 に答える
0

私はこれがどんな種類の保護も提供しないと思います。攻撃側のサイトはxmlhttprequest、クロスサイトリクエストフォージェリを使用してチェックをバイパスする可能性があります。

于 2010-07-23T07:05:50.047 に答える
0

簡単な答え:いいえ。攻撃者は、Ajax自身を使用してWebサイトを攻撃します。各ajaxリクエスト中に更新する、ライフタイムは短いが長すぎないランダムトークンを生成する必要があります。

複数のajaxリクエストを同時に実行している可能性があるため、JavaScriptでトークンの配列を使用する必要があります。

于 2010-07-23T07:16:28.057 に答える
0

xmlhttprequestは通常、クロスサイトリクエストフォージェリに対して脆弱ではないため、実行していることは安全です。

これはクライアント側の問題であるため、最も安全な方法は、ブラウザのセキュリティアーキテクチャを確認することです:-)

(これは要約です。この質問は非常に紛らわしいので、この回答を追加します。投票の内容を見てみましょう)

于 2010-07-26T08:37:09.680 に答える
0

いいえ、これは簡単に回避できません。このヘッダーとその資格情報を含むリクエストを含むサーバーにクロスドメインフラッシュリクエストを行うことで、https ://www.geekboy.ninja/blog/exploiting-json-crossを参照してください。 -site-request-forgery-csrf-using-flash /?unauthorized = 6685&moderation-hash = 91554c30888cfb21580f6873e0569da0

CSRFから保護する最善の方法は、ヘッダーまたはパラメーターに各リクエストの秘密鍵を含めることです。

于 2020-05-10T12:12:17.827 に答える