ホームページ > バックエンド開発 > PHPチュートリアル > クロスサイト リクエスト フォージェリの CSRF 攻撃と防御

クロスサイト リクエスト フォージェリの CSRF 攻撃と防御

高洛峰
リリース: 2016-10-17 10:46:53
オリジナル
1320 人が閲覧しました

1.CSRFとは何ですか?

CSRF(クロスサイトリクエストフォージェリ)、中国語名:クロスサイトリクエストフォージェリ、別名:ワンクリック攻撃/セッションライディング、略称:CSRF/XSRF。

2. CSRF は何ができるのですか?

CSRF 攻撃は次のように理解できます。攻撃者はあなたの ID を盗み、あなたの名前を使って悪意のあるリクエストを送信します。 CSRF ができることには、あなたの名前で電子メールやメッセージを送信したり、アカウントを盗んだり、さらには商品の購入や仮想通貨の送金などが含まれます。引き起こされる問題には、個人のプライバシーと財産のセキュリティの漏洩が含まれます。

3. CSRF の脆弱性の現状

この CSRF の攻撃手法は 2000 年に外国の安全保障関係者によって提案されましたが、中国で注目を集め始めたのは 2006 年になってからでした。 NYTimes.com (ニューヨーク タイムズ)、Metafilter (大規模なブログ Web サイト)、YouTube、Baidu HI など、国内外の CSRF 脆弱性がそれぞれ暴露されました。しかし現在、インターネット上の多くのサイトはまだこれに対して準備ができていません。セキュリティ業界では CSRF を「眠れる巨人」と呼ぶほどです。

IV. CSRFの原則

CSRF攻撃を完了するには、被害者は次の2つのステップを順番に完了する必要があります:

1. 信頼できるWebサイトAにログインし、ローカルでCookieを生成します。

2. Aからログアウトせずに、危険なWebサイトBにアクセスします。

これを見て、「上記2つの条件のうち1つを満たさなければ、CSRFの攻撃を受けることはない」と言うかもしれません。はい、その通りですが、次のような状況が起こらないとは保証できません:

1. Web サイトにログインした後、タブ ページを開いて別の Web サイトにアクセスしないという保証はできません。

2. ブラウザを閉じた後、ローカル Cookie がすぐに期限切れになり、最後のセッションが終了することを保証することはできません。 (実際には、ブラウザを閉じることでセッションを終了することはできませんが、ほとんどの人はブラウザを閉じることがセッションのログアウト/終了と同等であると誤解しています...)

3. 上の写真のいわゆる攻撃 Web サイト、それは信頼できる、頻繁にアクセスされる Web サイトに他の脆弱性がある可能性があります。

上記は CSRF 攻撃の概念について簡単に説明したもので、以下でいくつかの例を使用して特定の CSRF 攻撃を詳しく説明します。ここでは例として銀行振込操作を使用します (単なる例であり、実際の銀行 Web サイトはそうではありません)。とても愚かです:>)

例1:

銀行振込操作を完了するためにGETリクエストを使用する銀行のWebサイトA、例: http://www.mybank.com/Transfer.php?toBankId=11&money=1000

危険なWebサイトBには、次のようなHTMLコードが含まれています:

クロスサイト リクエスト フォージェリの CSRF 攻撃と防御

まず、銀行のWebサイトAにログインし、次に危険なWebサイトBにアクセスします。 1,000元足りない....

これはなぜですか?その理由は、銀行 Web サイト A が HTTP 仕様に違反しており、GET リクエストを使用してリソースを更新しているためです。危険な Web サイト B にアクセスする前に、あなたはすでに銀行の Web サイト A にログインしており、B は GET を使用してサードパーティのリソースを要求します (ここでのサードパーティとは銀行 Web サイトを指します。本来、これは法的な要求でしたが、ここでは犯罪者が取得したものです)これを利用すると、ブラウザは銀行 Web サイト A の Cookie を取得して、リソース「http://www.mybank.com/Transfer.php?toBankId=11&money=1000」を取得するための Get リクエストを発行します。その結果、銀行 Web サイトのサーバーはリクエストを受信した後、リソースの更新操作 (転送操作) であると考えたため、すぐに転送操作を実行しました...

例 2:

上記の問題を解決するには、 POST リクエストを使用することを決定した銀行は、転送操作を完了します。

銀行ウェブサイト A の WEB フォームは次のとおりです:

    <form action="Transfer.php" method="POST">
    <p>ToBankId: <input type="text" name="toBankId" /></p>
    <p>Money: <input type="text" name="money" /></p>
    <p><input type="submit" value="Transfer" /></p>
  </form>
ログイン後にコピー

バックグラウンド処理ページ Transfer.php は次のとおりです:

    <?php
    session_start();
    if (isset($_REQUEST[&#39;toBankId&#39;] && isset($_REQUEST[&#39;money&#39;]))
    {
        buy_stocks($_REQUEST[&#39;toBankId&#39;], $_REQUEST[&#39;money&#39;]);
    }
  ?>
ログイン後にコピー

危険なウェブサイト B にはまだ HTML コードのみが含まれています:

クロスサイト リクエスト フォージェリの CSRF 攻撃と防御

  和示例1中的操作一样,你首先登录了银行网站A,然后访问危险网站B,结果.....和示例1一样,你再次没了1000块~T_T,这次事故的原因是:银行后台使用了$_REQUEST去获取请求的数据,而$_REQUEST既可以获取GET请求的数据,也可以获取POST请求的数据,这就造成了在后台处理程序无法区分这到底是GET请求的数据还是POST请求的数据。在PHP中,可以使用$_GET和$_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request一样存在不能区分GET请求数据和POST数据的问题。

  示例3:

  经过前面2个惨痛的教训,银行决定把获取请求数据的方法也改了,改用$_POST,只获取POST请求的数据,后台处理页面Transfer.php代码如下:

   <?php
    session_start();
    if (isset($_POST[&#39;toBankId&#39;] && isset($_POST[&#39;money&#39;]))
    {
        buy_stocks($_POST[&#39;toBankId&#39;], $_POST[&#39;money&#39;]);
    }
  ?>
ログイン後にコピー

  然而,危险网站B与时俱进,它改了一下代码:

<html>
  <head>
    <script type="text/javascript">
      function steal()
      {
               iframe = document.frames["steal"];
               iframe.document.Submit("transfer");
      }
    </script>
  </head>
  <body onload="steal()">
    <iframe name="steal" display="none">
      <form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php">
        <input type="hidden" name="toBankId" value="11">
        <input type="hidden" name="money" value="1000">
      </form>
    </iframe>
  </body>
</html>
ログイン後にコピー

如果用户仍是继续上面的操作,很不幸,结果将会是再次不见1000块......因为这里危险网站B暗地里发送了POST请求到银行!

  总结一下上面3个例子,CSRF主要的攻击模式基本上是以上的3种,其中以第1,2种最为严重,因为触发条件很简单,一个就可以了,而第3种比较麻烦,需要使用JavaScript,所以使用的机会会比前面的少很多,但无论是哪种情况,只要触发了CSRF攻击,后果都有可能很严重。

  理解上面的3种攻击模式,其实可以看出,CSRF攻击是源于WEB的隐式身份验证机制!WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!

五.CSRF的防御

CSRF 的防范机制有很多种,防范的方法也根据 CSRF 攻击方式的不断升级而不断演化。常用的有检查 Refer 头部信息,使用一次性令牌,使用验证图片等手段。出于性能的考虑,如果每个请求都加入令牌验证将极大的增加服务器的负担,具体采用那种方法更合理,需要谨慎审视每种保护的优缺点。

1. 检查 HTTP 头部 Refer 信息,这是防止 CSRF 的最简单容易实现的一种手段。根据 RFC 对于 HTTP 协议里面 Refer 的定义,Refer 信息跟随出现在每个 Http 请求头部。Server 端在收到请求之后,可以去检查这个头信息,只接受来自本域的请求而忽略外部域的请求,这样就可以避免了很多风险。当然这种检查方式由于过于简单也有它自身的弱点:

a) 首先是检查 Refer 信息并不能防范来自本域的攻击。在企业业务网站上,经常会有同域的论坛,邮件等形式的 Web 应用程序存在,来自这些地方的 CSRF 攻击所携带的就是本域的 Refer 域信息,因此不能被这种防御手段所阻止。

b) 同样,某些直接发送 HTTP 请求的方式(指非浏览器,比如用后台代码等方法)可以伪造一些 Refer 信息,虽然直接进行头信息伪造的方式属于直接发送请求,很难跟随发送 cookie,但由于目前客户端手段层出不穷,flash,javascript 等大规模使用,从客户端进行 refer 的伪造,尤其是在客户端浏览器安装了越来越多的插件的情况下已经成为可能了。

2. 使用一次性令牌,这是当前 Web 应用程序的设计人员广泛使用的一种方式,方法是对于 Get 请求,在 URL 里面加入一个令牌,对于 Post 请求,在隐藏域中加入一个令牌。这个令牌由 server 端生成,由编程人员控制在客户端发送请求的时候使请求携带本令牌然后在 Server 端进行验证。但在令牌的设计上目前存在着几个错误的方案:

a) 使用和 Session 独立的令牌生成方式。这种令牌的值和 Session 无关,因此容易被其他用户伪造。这里的其他用户指的是当前 Web 应用程序的其他用户和活跃在网络传输阶段各个设置上的监听者,这种恶意用户可能使用自己的令牌来进行替换以便达到伪造的目的。

b) 完全使用 Session 认证信息作为令牌的生成方式。这种保护方式对于保护 CSRF 是起了作用的,但是可能会造成其他危害,具体来说,如果某些 URL 或者网页被拷贝下来与其他人共享,那么这些 URL 或者拷贝下来的网页中可能会含有用户的会话信息,这种信息一旦被恶意用户获得,就能造成极大的危害。

因此,一个正确的令牌设计应该是使用 Session 信息做 Hash,用得出的哈希值来做 CSRF 的令牌。

3. 検証画像を使用する この方法の目的は、ロボットによるブルート フォース攻撃を防ぐことです。ただし、CSRF 防止の観点からは、検証画像とワンタイム トークンを組み合わせて二重保護する、比較的高いセキュリティ要件を備えたアプリケーションもいくつかあります。このイメージ検証情報は悪意のあるプログラムがクライアント上で識別することが難しいため、より強力な保護を提供できます。クライアントのブラウザがすでに安全でない環境にある可能性がある場合 (たとえば、クライアントのセキュリティ レベルが低いレベルに設定されている、クライアントのブラウザに安全でないプラグインがインストールされているなど)。

上記は、CSRF を防ぐためのより一般的な方法の一部にすぎません。Web 開発者は、アプリケーションの機能の理解に基づいてセキュリティ レベルの要件を決定し、さまざまな保護手段を使用することもお勧めします。同じアプリケーションを保護するためにプログラム内で複数の方法が使用されます。

注: 高速道路に料金所を設置するのと同じように、防御を追加するとパフォーマンスにも大きな影響を与えます。重要な操作にのみ防御を追加することをお勧めします。慎重にご検討ください。


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート