クロスサイトリクエスト攻撃(CSRF)からajaxアプリケーションを保護する

ごく最近、私はCSRF攻撃からajaxで完全に構築されたWebアプリケーションを保護する仕事をしました。



そのような攻撃のメカニズムは何ですか? 一番下の行は、ユーザーの認証データの下で別のサイトからリクエストを実行することです。 たとえば、 example.com / login / dropmeアカウントを削除するアクションがあります。 CSRF攻撃に対する保護がない場合、必要なWebサイトにタグを配置できます。

<img src="http://example.com/login/dropme">
      
      





ユーザーが準備したページにアクセスしてすぐにimgのコンテンツをアップロードすると、example.comのアカウントは削除されます。 これからの保護について説明します。





攻撃メカニズム



攻撃の本質は、別のサイトからURLでコンテンツをロードするタグを設定することです。 このようなタグには、img、スクリプト、リンク(cssの場合)、iframe、およびすぐには思いつかなかった他のタグを使用できます。





標準的な保護方法とそれらが私に合わなかった理由



保護する簡単な方法があります:HTTP_REFERERをチェックします。 ブラウザはこのヘッダーを匿名モードで送信しない可能性があるため、私には向いていませんでした。 この場合、すべての「匿名」ユーザーはこのような攻撃を受けやすくなります。



より高度な保護方法があります。URLにトークンを追加し、アクション中にトークンをチェックします。 なぜこれが私に合わなかったのですか? さまざまなページおよびアクションへの100以上のリンクが既に存在する既製のアプリケーションがあり、それらはURL転送を伴う関数呼び出しの形式ではなく、<a href="..."> </a>の形式のコードで実行されます。したがって、さらに編集する必要があります100か所。 何かを忘れる危険があります。



解決策



解決策はすぐに見つかりました。 アプリケーションのすべてがajaxを介して機能するため、ajaxリクエストにトークンヘッダーを追加できます。 私たちの場合、jQueryではこれは次のように行われます。

 $.ajaxSetup({ headers: { 'X-Csrf-Token':token } });
      
      





Ajaxリクエストに加えて、新しいタブ、そして最も重要なことには、アプリケーションへの最初のエントリに開口部があるかもしれません。 これらのリクエストにはトークンは含まれていませんが、処理する必要があります。 それらを処理するには、次のソリューションを使用します。 リクエストにトークンが含まれていない場合は、次のHTMLコードを提供します。



 <html> <body> <?php echo $loading_text; ?> <script type='text/javascript'> <?php /** check img and other left src tags **/ ?> if (parent.document.location.href == document.location.href){ <?php /** check iframe **/ ?> document.location.href='<?php echo $url; ?>'; } </script> </body> </html>
      
      





ここで、$ urlは、最後に署名された&csrf_tokenでリクエストが行われたURLです。 そのようなコードがimg、script、linkタグに与えられた場合、それは実行されず、攻撃者は目標を達成しません。 コードがiframeに埋め込まれている場合、ifの条件はその実行を遮断します。



したがって、GETパラメータからトークンを処理し、それをヘッダー用にクライアント側に渡す方法を学習する必要があります。 実際にそれを与えることは特に問題ではありません。 example.com/profileなどのページをロードした後常にexample.com/profile?csrf_token=ページにアクセスします ...

したがって、jsを使用してgetパラメーターからトークンを抽出することは残ります。



あとがき



上で説明したものはすべてライブラリにまとめられgithubに投稿されました。 そのライブラリにはいくつかの欠陥がありますが、時間が来たらすぐに修正します。 このライブラリはすでに実際のプロジェクトに取り組んでいます。



All Articles