第1回「CSRF対策」CSRF HTML・PHP

こんにちは。今回は「CSRF対策」について触れていきます。

 

少しボリューム多めです。20分くらいかけて、ゆっくり読んでください。

目次

・「CSRF」とは

・「どういったWebサイトが危ない?」

・「CSRF対策」

・「リロード2重登録対策」(追記分)

・「過去の被害(大量のはまちゃん事件)」

・まとめ

・今回の記事を書くにあたって参考にしたサイト

 


・「CSRF」とは

 CSRFとは、「クロスサイトリクエストフォージェリ」の略です。

言いやすく「シーサーフ」と呼ばれます。

また、「リクエスト強要」と呼ばれることもあります。

 

画像:引用元

どういった被害が出ているかというと

  1. 自分で書いた記憶のない書き込み (mixi や その他のSNS )
  2. 覚えのない商品購入       (通販サイト)
  3. パスワードが勝手に変更されている(フォームページが存在するWebサイト)
  4. 非公開にしていた情報が公開に  ( mixi  や その他のSNS )

といったものがあります。

 

※技術的な話(ここは飛ばしてもOKです。)
  悪意をもったエンジニアが作ったWebページ。
 そのページを開くと、SESSIONやCOOKIEの情報を付与されてしまいます。
 その状態で、CSRF対策を行っていないWebサイトにアクセスした場合、
 問題が発生する可能性があります。

 

 

参考URL:【6】CSRF(クロスサイトリクエストフォージェリ:リクエスト強要)って一体何? どう対策すればいいの?


・「どういったWebサイトが危ない?」

 

被害を受けるサイトは以下です。

  • ユーザーが、書き込みをできるSNSサイト
  • 通販サイト
  • フォーム画面にて、自分の情報を登録する機能があるWebページ
  • パスワードを変更できるWebページ

 

参考URL:【6】CSRF(クロスサイトリクエストフォージェリ:リクエスト強要)って一体何? どう対策すればいいの?


・「CSRF対策」

  1. 確定処理の前に認証を行う   (パスワード変更時)
  2. リファラを確認する      (フォーム、書き込み部分、通販サイト、etr・・・)
  3. ワンタイムトークンを利用する (パスワード変更時)

 

●確定処理の前に認証を行う

 パスワードなど、大切な情報を変更する場合は、以下のような順番にします。

変更ページにて、「新しいパスワード」を入力

推移したページで「変更する前のIDとパスワード」を入力・確定ボタン

「パスワード変更しました」

一度、「変更する前のIDとパスワード」ページを間に入れることで、悪意のある攻撃を回避します。

ですが、すこしユーザーが「めんどくさい」と思うかもしれません。次の方法では、ユーザーに負荷がかかりません。

 

リファラを確認する 

「リファラ」とは、このWebページを開く前に、開いていたWebページのURLです。

PHPでは、以下で求められます。

//リファラ
$_SERVER['HTTP_REFERER'];

 

データを登録する前に、この「リファラ」が、正しいか判断してから、登録処理を行います。

今開いているWebページのURLと、一緒かと確認するなら、

if($_SERVER['HTTP_REFERER'] == (empty($_SERVER["HTTPS"]) ? "http://" : "https://").$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']){

   //リファラが正しいURLだったら、行う処理をここに記述します。

}

と書くと、大丈夫です。

※POSTで、フォーム情報を送る場合前提です。

 しかし、リファラは、HTTPヘッダーの一つです。書き換えられることが、ないとは限りません。

本当に悪意のある人しか書き換えないでしょうが、少し不安です。

次の「ワンタイムトークン」を紹介します。

 

 

ワンタイムトークンを利用する

 「ワンタイムトークン」とは・・・

難しく考えることはございません。簡単な文字列です。

「1」や「300」や「2107」などの数値です。

 

「固定トークン」なら、

例えば、「あ」とか「テスト」とか「testtest21」とか、自由な文字列です。

 

その自分でつくった文字列を、フォーム情報に付与します。

実際に登録処理を行う前に、その「ワンタイムトークン」文字列が、正しい文字列か判断し、処理する流れです。

 

フォーム側「固定トークン」(PHPの場合)      実際使われるときは「テスト」の文字列を自由な文字列に変更してください。

<!--  送信するワンタイムトークン  -->

<form  method="POST">

~~メインのフォーム情報~~

<input type="hidden" name="tokun" value="<?php echo md5("テスト"); ?>" >

</form>

 

登録処理のまえの判断「固定トークン」(PHPの場合)

if($_POST["tokun"] == md5("テスト")){

//ここに、ワンタイムトークンが正しかった時の処理を記述します。

}

参考URL:とっても簡単なCSRF対策

 

通常、ワンタイムトークンは、乱数を使用するようです。

ただし、その方法であっても、まだまだセキュリティーが甘いという人もいます。

このWeb APIってCSRF対策出来てますか?って質問にこたえよう

上記のサイトでは、違う方法を書いていますが、著者自身も、「デメリットがある」と書いています

 

セキュリティー面も、突き詰めていくと、終わりがないと思います。

このWeb APIってCSRF対策出来てますか? には、もっと詳細にこだわった、CSRF対策が書いてあります。気になる方はご参考にしてみてはいかがでしょうか。

 

自分も新しい知識がついたら、この記事を追記しようかな。

 

参考URL:意図しない処理が実行されるCSRFとは?概要と対策


・「リロード2重登録対策」(追記分)

 POSTやGETで、受け取ったデータを消しても、ページを再読み込み(リロード)や、F5を押す(リロード)と、何度も同じ処理をしてしまう場合があります。

失敗例

<?php
//POST GET を初期化
$_POST = array();
$_GET = array();
?>

POSTやGETは、ブラウザに保存されるものなので、閲覧履歴も消しても残ってしまうのです。

 

 解決策としましては、$_SESSION を使います!

情報を入力するページ

<?php

session_start();

//CSRF対策
$_SESSION['token'] = md5("暗号化する独自の文字列");

?>

情報を受け取り、登録処理などを行うページ

<?php

session_start();

// セッションに入れておいたトークンを取得
$session_token = isset($_SESSION['token']) ? $_SESSION['token'] : '';

if($session_token == md5("暗号化する独自の文字列")){
    //登録処理など、ここに記述。

    //一度、処理が終わったら、セッションに入れておいたトークンを削除します。
    
    // セッションに保存しておいたトークンの削除
    unset($_SESSION['token']);
    // セッションの保存
    session_write_close();
    // セッションの再開
    session_start();
}

?>

 これで、登録ページを何度もリロードされても、同じ登録処理を行う事はありません!

※ただ、一度登録をしてから、ブラウザの違うタブで「情報を入力するページ」を開いた場合は、セッションが保存されるので、ご注意ください。

 

参考URL:PHPでの二重送信対策が、効いていない?


・「過去の被害(大量のはまちゃん事件)」 (飛ばしてもOKです)

 

 2005年4月ごろ、「mixi」というSNSサイトで、「ぼくははまちゃん!」と事件が勃発しました。

あるWebサイトを経由することで、そのまま「mixi」にアクセスしてしまうと、

まるで、自分が日記を書いたように、「ぼくはまちゃん!」という日記が登録されてしまう事件でした。

 

 ただ、それはウィルスやスパム攻撃ではありませんでした。

Webプログラミングの脆さ(脆弱性)とよく言われる部分です。

正しく、プログラミングすることで、この方法を回避する事ができるんじゃないでしょうか。

 

 

参考URL:大量の「はまちちゃん」を生み出したCSRFの脆弱性とは?


・まとめ (飛ばしてもOKです)

 

 セキュリティー面も大事ですね。

以前、ワードプレスのプラグインを作った際に、「リファラ」を確認するというのが参考サイトに書いてありました。

なんか無意識に、対策できてたのかなぁと、なごむ一日でした。

 


・今回の記事を書くにあたって参考にしたサイト

大量の「はまちちゃん」を生み出したCSRFの脆弱性とは?

意図しない処理が実行されるCSRFとは?概要と対策

【6】CSRF(クロスサイトリクエストフォージェリ:リクエスト強要)って一体何? どう対策すればいいの?

PHPでの二重送信対策が、効いていない?

参考にさせて頂いたサイトの管理者様、今回もありがとうございました。

,,,

Comments

Leave a comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です