前回に引き続き、セキュリティ対策の見直しを行います。
- PEAR::DBでデータ登録する際のプレースホルダ利用
- セッションIDの再生成(session_regenerate_id)
- hidden値の書き換え
- リンク元のURL照合
今回は上記のうち、3,4について考えます。
前回に引き続き、セキュリティ対策の見直しを行います。
今回は上記のうち、3,4について考えます。
勉強記録1-6で、ユーザー認証システムは概ね、かたちになりました。
(ユーザー登録からログイン、ログアウトまで)
ここで一度、これまでのロジックを見直し、セキュリティ対策を見直します。
今回は上記のうち、1,2について考えます。
勉強記録3で、ユーザーデータ、Emailデータの重複確認のために、PEAR::DBを利用して、マッチングを行いました。
このコードの中で、WHERE後の変数取り扱いが、セキュリティホールになりうることに気が付きました。
($usernameなどに悪意あるデータを入れられる可能性があり、かつエスケープ処理していない)
修正前のマッチング処理
/* 入力されたユーザーIDとパスワードを変数に取得 */
$username = $_POST["username"];
$email = $_POST["email"];
/* PEAR::DBを利用してユーザー名とメールアドレスの有無を取得
すでに存在する場合、各変数にユーザーId、メールアドレスのみの配列が生成される
require_once("DB.php");
$dsn = "mysqli://pear:peartest@localhost/pear";
$myDB = DB::connect($dsn);
$user_exist = $myDB -> getRow("SELECT username FROM auth WHERE username='$username' ");
$email_exist = $myDB -> getRow("SELECT email FROM auth WHERE email='$email' ");
この箇所を、PEAR::DBのプレースホルダを利用して対応します。
修正後のマッチング処理
/* 入力されたユーザーIDとパスワードを変数に取得 */ $username = $_POST["username"]; $email = $_POST["email"]; /* PEAR::DBを利用してユーザー名とメールアドレスの有無を取得 すでに存在する場合、各変数にユーザーId、メールアドレスのみの配列が生成される require_once("DB.php"); $dsn = "mysqli://pear:peartest@localhost/pear"; $myDB = DB::connect($dsn); $user_exist = $myDB -> getRow("SELECT username FROM auth WHERE username=? ", array($username)); $email_exist = $myDB -> getRow("SELECT email FROM auth WHERE email=? “, array($email));
プレースホルダについては、書籍「PEAR入門」の02.01章にも詳しく書かれておりました。
最初に、この書籍を見たときには
「プレースホルダってなんだろう?」
と思っておりました(恥)。
自分で書いたコードのセキュリティを確認して、プレースホルダを利用して書き直すと、その重要性が改めてわかりますね。
プレースホルダについては、いつもお世話になっているMTハッカー・ToI企画の天野さんからご指摘いただきました。天野さん、いつもありがとうございます!
オンラインでは、PHPBookさんの「クエリの実行」ページにも、詳しく書かれております。
今回のユーザー登録ロジックでは、単純にsession_start()関数を利用してセッションを生成しておりました。
ここで、セッションIDの値が何らかの原因で判明した場合、セッションハイジャック攻撃の危険性が発生します。イメージとしてはこんな感じでしょうか。
セッションIDの固定化によるハイジャック攻撃を防ぐために、セッションIDの値を都度書き換える「sesshion_regenerate_id()関数」を利用して、セッションIDの変更を実行することにします。
入力フォームでデータを入力後、確認画面に移動する際に、セッションIDの変更を試みます。
以下「勉強記録6」で作成したロジックの一部と、修正後のロジックになります。
コード作成には、書籍「PHP逆引きレシピ」および「PHPプロ!」さんの記事を参考にさせていただきました。
修正前のregistConfirm.php(冒頭部)
<?php session_start(); ?>
修正後のregistConfirm.php(冒頭部)
<?php
session_start();
/* 現在のセッションIDを変数に格納 */
$old_id = session_id();
/* session_regenerate_id関数で、セッションIDを変更 */
session_regenerate_id(TRUE);
/* PHPのバージョンが5.1.0未満の場合は、
前セッションIDファイルを消去する */
if(version_compare(PHP_VERSION, '5.1.0', '<')) {
unlink(session_save_path() . '/sess_' . $old_session_id);
}
?>
次回は
について考えてみたいと思います。
先日、奥さんがアメリカンビスケットを焼いてくれました。
京都に本店があるアメリカンケーキのお店「松之助」さんのビスケットを買ってきたのですが、それがたいそう美味しかったのです。
それに刺激を受けて、作ったようです。
ところで、この料理、ケンタッキーフライドチキンでも、「ビスケット」という名前で販売していますが、何回見ても、「スコーン」と区別がつきません。何が違うんでしょうか。
昨年途中で中断した、「奥さんに代わって料理を作る日」。
久々に復活です。
今年最初の料理は、きのこリゾット、ポークソテー、あさりとトマトの野菜スープ。

それぞれ、以下のレシピを参考にしました。
「あさりとトマトの野菜スープ」=>こうちゃんの簡単料理レシピ
(調味料の配分や材料などは、かなりオリジナルにしてしまってますが・・・)
好評だったようで、良かった良かった。
リゾットは初めて作りました。みんな簡単、というけれど、きちんとつくると以外に手数がかかるんだな、という印象でした。
来月は、どんな料理をつくろうかな。
和食でもつくろうかな。
前回までは、入力フォーム表示・登録ロジック(registForm.php)と、入力データチェックロジック(registCheck.php)の2ファイルで、ユーザー情報の登録処理を行いました。
今回は、入力フォームに情報入力後、確認画面を経て、登録完了を行うようにロジックを分けたいと思います。
流れとしては、以下のようになるかと思います。
今回は、メールアドレスとパスワードのチェックについて考えてみます。
その前に、テストで作成したフォームを修正します。
テストでは、パスワードの入力欄は1つのみでしたが、入力欄を2つに分け、パスワード確認のために2回入力させるようにします。
1つ目のパスワード入力欄のnameは「password」
2つ目のパスワード入力欄のnameは「password2」としました。
続いて、メールアドレスのチェックを行います。
前回は、ユーザー情報の登録に当たって、最低限のチェックと登録まで、を実装しました。
今回は、入力されたユーザーIDのチェックを行います。
まず、登録ユーザーIDの仕様を以下のように定義しました。
上記に従って、ベリファイ用のルーチンを考えました。
1,2は前回実装済みなので、今回は3・4の処理について考えます。
僕は高校時代、演劇部に所属しており、
「大学生になったら、演劇も続けて、大好きな歴史の勉強もしたい」
と考え、入学したのが早稲田大学でした。
(大学時代は、今は作家として有名になった「古川日出男」さんと一緒に、演劇をやっておりました)
第三舞台は、ちょうど僕が入学する頃に、人気が出始めた劇団です。
初めて第三舞台を見たときは、あまりの凄さにカルチャーショックを受けました。
「演劇って、こんなに面白いんだ!」と、打ちのめされる思いがしました。
2001年、「ファントム・ペイン」を最後に、10年の活動封印を宣言した「第三舞台」。
今年でちょうど、10年。
復活するのかな?
「虚構の劇団」もノってきているし、このまま封印が続くんじゃないかな・・・
と思っていたところ。
先日、放送作家をやっている先輩と、お酒を飲んでいるときに
「知らないの?今度復活公演やるらしいよ。ニュースに出てたよ」
と、教えてもらいました。
な、なんとびっくり!
登録ユーザーのログイン・ログアウトの次は、実際にユーザーをユーザーDBに登録するためのロジックを開発してみます。
今回の作業概要は以下のとおりです。
今回は、PEAR::AUTHを利用してログインしたユーザーの、タイムアウト処理です。
ウェブサービスを利用していると、必ずといっていいほど、ログイン済みユーザーのタイムアウト処理を行っています。
タイムアウト処理は、大きく分けると、次の2つがあると思います。