ユーニックス総合研究所

記事内に広告を含む場合があります。

  • home
  • archives
  • web-csrf

CSRFとは?悪意のあるリクエストを別のサイトから送信する

  • 作成日: 2020-09-19
  • 更新日: 2023-12-24
  • カテゴリ: Web

CSRFとは?

CSRF(クロスサイトリクエストフォージェリ)とは、悪意のあるサイトにユーザーを誘導し、そのサイトから悪意のあるリクエストを別のサイトに送信する攻撃手法です。
「フォージェリ」とは「偽造」という意味です。

つまりCSRFは「別のサイトへのリクエストを偽造する」という意味になります。

CSRFのストーリー

CSRF攻撃をされるユーザーのストーリーは以下のようなものです。

  1. A君が掲示板で誰かが貼ったURLをクリックした
  2. 利用しているSNSの認証画面が開いた
  3. A君は認証画面のボタンをクリックした

↑のストーリーでは、A君がCSRFによる攻撃を受けています。
CSRFの具体的な内容とはどのようなものでしょうか?

CSRFの内容

CSRFを行うアタッカーを例にその攻撃内容を見てみます。

トラップサイトの用意

まずCSRFを行うアタッカーは、悪意のあるWebサイトを作成します。
このWebサイトには有名SNSの認証画面にそっくりなページを配置します。
このページはSNSへ以下のような投稿のリクエストを送信するようになっています。

●月●日、○○を爆破する!  

ターゲットの誘導

次にアタッカーはそのSNSの話題が書き込まれている掲示板に、さきほどの悪意のあるWebサイトのURLを貼り付けて投稿します。
投稿内容は↓のようなものです。

みんな~!SNSがタイムセールスはじめたって!  
https://xxxx.xxx/xxxx/xxxx  

その掲示板に訪れていたSNSのユーザーでもあるA君がさきほどのリンクをクリックします。
するとブラウザ上に先ほどのトラップサイトが開きます。

スクリプトによるリクエストの送信

トラップサイトが開くと偽のSNSの認証画面がA君の目の前に現れます。
A君はそれが偽物だと気付かずに認証画面のボタンをクリックしてしまいます。
すると偽のページはSNSに対して先ほどの爆破予告のリクエストを送信します。

A君のブラウザにはSNSのCookieが保存されており、SNSはそのCookieを認識します。
有名SNSはそのリクエストを受け付けてしまい、SNSにログインしていたA君のアカウントから先ほどの爆破予告が投稿されてしまいます。

しかしA君はSNSに自分のアカウントから爆破予告が投稿されたことには気づかず、ネットサーフィンを続けます。

通報と逮捕

SNSのユーザーがA君の爆破予告を見て警察に通報し、A君は逮捕されてしまいました。
A君自身は爆破予告をしていないのですが、爆破予告のアカウントからA君が特定されたのです。

ここで紹介した内容はCSRFによる攻撃の一例です。

原因

なぜこのような攻撃が可能になってしまうのでしょうか?
今回の例では、原因はSNSの脆弱性にあります。

SNSの脆弱性

SNSはSNS以外のサイトからの投稿リクエストも受け付けて処理してしまっています。
そのため先ほどのような外部のサイトからの不正なリクエストもSNSは通してしまいます。

対策

CSRFの脆弱性への対策としては、SNSが外部のサイトからのリクエストを許可せずに通さないということが大事です。
外部のサイトからのリクエストは一切信用せず、投稿機能のような悪意のある攻撃が可能になる機能を外部から実行できないようにします。

再認証を行う

重要な変更を行う機能は、その都度ユーザーに再ログインさせるようにします。
こうすれば外部のサイトが投稿リクエストを送っても、再ログインしていないリクエストは弾くことができます。
しかしデメリットとしてはユーザーに再ログインの手間を生じさせます。

リファラを確認する

HTTPリクエストのヘッダーには「リファラ」というリクエストがどこから来ているのかを表す文字列があります。
ここをチェックすることでリクエストの正当性を確認することが可能です。
たとえばリクエストがSNSと同じドメインから来ていれば問題なし、リクエストが外部ドメインから来ていれば問題あり、と言う風にです。
しかし、HTTPリクエストのヘッダーは改ざん可能です。
そのためリファラのチェックは気休め程度のものでしかありません。

CSRFトークンによる対策

最近の一般的なWebアプリで使われているのがこのCSRFトークンによる対策です。
サイトがフォームを表示するときにワンタイムトークンを発行し、フォームに埋め込みます。
このとき、サーバー側でもトークンを保存しておきます。
そしてフォームからリクエストを送るときにこのトークンも一緒に送信します。
あとはサーバー側で保存したトークンとフォームから送信されたトークンが同じかどうかチェックし、同じであればリクエストを通し、同じなければ信頼性のないリクエストとして処理します。

こうすることでサイトが表示していないページ(=外部サイト)からのリクエストを遮断します。

おわりに

CSRFによる攻撃はおそろしいものです。
これを回避するには、利用するサイトをよく吟味するようにすることが大事です。
セキュリティ対策が行われていないサイトは利用しないようにしましょう。

また、不用意に掲示板などに貼られているリンクなどをクリックしないようにすることも大事です。
不審なサイトには訪問しないようにして、あやしげな誘導には乗らないようにしましょう。

参考