こんにちは。サイオステクノロジーの川田です。
前回のXSSに続いて、今回はCSRF(クロスサイトリクエストフォージェリ)という脆弱性をご紹介致します。
私が新卒の頃、初めてCSRFと聞いて「かっこいい名前」と思いました。そんなかっこいい脆弱性の名前ですが、どんな恐ろしいことが起きてしまうのか一緒に学んでいきましょう!
CSRF(クロスサイトリクエストフォージェリ)とは
Webアプリケーションの脆弱性の一種となっているのが、CSRF(クロスサイトリクエストフォージェリ)です。ログイン済みのブラウザに悪意のあるサイトをユーザーにクリックさせ、意図しない処理を実行させる脆弱性です。
では、図で確認してみましょう。
利用者はいつも利用するサイトにIDとPasswordを入力し、ログインボタンをクリックします。
※ログインが成功するとセッションIDはCookieに保持されます。
利用者はログイン状態のブラウザで様々なサイトを閲覧します。
その中に攻撃者によって埋め込まれた悪意のあるサイトを知らずにクリックしてしまいます。
先ほどログインをしたサイトにアクセスするとCookieで保持されていたセッションIDが送信され、正しいセッションIDとして受理されます。
攻撃者が仕込んだスクリプトにより利用者の意図しない動作がWebサーバーに送信されてしまい、「掲示板への書き込み」や「強制退会」等の操作が行われてしまいます((((;゚Д゚))))
「はまちちゃん」騒動
SNSの一つであるmixiで「ぼくはまちちゃん! こんにちはこんにちは!!」という文章が大量に書き込まれる事案が発生しました。
この騒動はmixiにログイン状態のまま、仕込まれたURLをクリックしたことによって意図しない日記が書き込まれてしまったのです。
では実際の画面で動かしてみましょう!
CSRF攻撃を実際にしてみよう!
こちらは簡単なログイン画面になります。
DBに登録されているIDとパスワードを入力し、「login」ボタンをクリックします。
そして掲示板入力画面に遷移します。
コメントを入力し、登録ボタンをクリックすると先ほど入力した内容が一覧画面に表示されます。
CSRF対策はされていない画面になります。
セッションIDはCookieに保持されます。PHPで作成しているため「PHPSESSID」という名前になります。
では悪意のあるサイトから投稿してみましょう。
こちらの画面はボタンをクリックすると、掲示板に投稿されるようにJavaScriptのAjax(非同期処理)を用いて実装をしました。
ログイン状態のブラウザから「押してください」をクリックすると、、、、、、
入力画面から処理を行っていないのに悪意のあるサイトから投稿されてしまいました!!!
これがCSRF攻撃になります。
CSRF対策をしてみよう!
対策方法は「トークンを利用して正しいリクエストであるかをチェックする」ことです。
hiddenとセッションにトークン値をセットしておきます。
POSTで送信されたトークンとセッションに保存しているトークンの値が一致していれば正しいリクエストと判断できます。
トークン値が空や異なる場合はエラーとして処理ができるのです。
実装してみましょう!
PHP側ではランダムな英数字を生成して、セッションにトークンをセットしました。
入力画面のHTML側にはセッションに登録したトークン情報をhiddenにセットしています。
<input type="hidden" name="token" value="<?php echo $_SESSION['token']; ?>">
ブラウザ上でページのソースを表示するとトークンがセットされていることがわかります。
また、PHP側ではバリデーションチェックやDB登録の処理を行う前にセットされているトークンが一致しているかの条件を追記する必要があります。
if ($_POST['token'] === $_SESSION['token']){
ではCSRF対策がされている画面にアクセスしてみます。先ほどと同様に悪意のあるサイトからボタンをクリック!
悪意のあるサイトからは投稿されませんでした!!!(∩´∀`)∩ワーイ
入力画面から登録ボタンをクリックすると正常に投稿されます!
今回はCSRFについての説明と対策でした!
最後までお読みいただきありがとうございました。