PHP: CodeIgniterをセキュアに使うチュートリアル
この記事は賞味期限切れです。(更新から1年が経過しています)
PHPフレームワークは数多く公開されておりますが、
中でも個人的にお気に入りなのはシンプル・軽量さが売りのCodeIgniterです。
» CodeIgniter – Open source PHP web application framework
この度Nettuts+でCodeIgniterをセキュアに使うためのチュートリアルが紹介されていました。
※2010/08/07 セッションエンコーディングの項で、キー文字列を入力した例を追記
CodeIgniter from Scratch: Security | Nettuts+
こちらがそのチュートリアルビデオなのですが…
35分と大変長いので、要点だけ下にまとめておきます。
ビデオではスクラッチから書いていて大変わかりやすいので、
時間がある時に見ておくと良いと思います!
英語ですが、コードだけ見ていても参考になります。
- パラメータに使用される文字を制限する
- パスワードエンコーディング
- SQLインジェクション対策
- クロスサイトスクリプティング対策
- セッションエンコーディング
- PHPのエラー表示を消す
- プライベートメソッドを使う
1. パラメータに使用される文字を制限する
CodeIgniterはURLの一部をメソッドの引数として受け取りますが、
そこで使用可能な文字をconfig.phpで厳しく管理しています。
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_-';
正規表現の書式で指定されているここの値を、より厳格にする事で
クライアント側からの予期せぬインプットを防ぐ事が出来ます。
制作するアプリケーションによって中身を精査すると良いでしょう。
2. パスワードエンコーディング
sha1やmd5等のPHPに既存の関数ではなく、
よりセキュアにエンコーディング出来るencryptライブラリの使用が推奨されています。
$this->load->library("encrypt");
$this->encrypt->encode($mypassword);
encryptライブラリは、キーとなる文字列を第二引数に指定する事で、
可逆エンコードする事も出来ます。
$key = "this is private key string";
$encoded_password = $this->encrypt->encode($mypassword, $key); // エンコード
$decoded_password = $this->encrypt->decode($encoded_password, $key); //デコード
cf) 暗号化クラス : CodeIgniter ユーザガイド 日本語版
3. SQLインジェクション対策
SQLインジェクション攻撃に備えて、
クライアント側からインプットされた値をDBに渡す前に消毒してやります。
$this->load->database();
$query = $this->db->query("SELECT * FROM users WHERE name = {$this->db->escape($name)}");
また、ActiveRecordクラスを使用する事で
最小限のスクリプティングでDBへアクセスする事が出来ます。
この場合、入力された値のエスケープは自動で行わるので、意識する必要がありません。
$this->load->database();
$query = $this->db->select("*")->from("users")->where("name",$name);
cf) Active Record クラス : CodeIgniter ユーザガイド 日本語版
4. クロスサイトスクリプティング対策
いわゆるXSSという奴です。
この攻撃に備えて、値のインプットとアウトプット両方において
フィルタをかけてやる必要があります。
■インプット
インプットは、$_POSTを使わずに入力クラスを用いて値を受け取りましょう。
$this->input->post("comment", true);
第二引数にtrueを渡す事で、XSSフィルタを入力された値に適用できます。
また、config.phpでの設定で、XSSフィルタリングをデフォルトでかける事が出来ます。
// /system/application/config/config.php
$config['global_xss_filtering'] = TRUE;
これで第二引数がなくともXSSフィルタがかかるようになりました。
単独でフィルタが使いたい場合は、xss_cleanメソッドを使いましょう。
$clean_string = $this->input->xss_clean($string);
■アウトプット
アウトプット時は、PHP組み込みのhtmlspecialcharsを用いるか、
htmlspecialchars($string);
または、CodeIgniterのヘルパ関数による出力をする事で
自動的にフィルタリングがかけられます。
$this->load->helper("url");
echo anchor($url);
5. セッションエンコーディング
CodeIgniterのセッションはPHP組み込みのセッションを使用せず、
独自のセッションデータを生成して利用します。
$this->load->library("session");
$this->session->set_userdata("user_id", 2); //セッションデータの入力
$this->session->userdata("user_id"); //セッションデータの取得
上のように、ログイン状態を保持する場合等に頻繁に使われますが、
cookieを覗いて見ると、user_idの値が丸見えになっていて大変危険です。
これを保護する為に、セッションエンコード用のキー文字列を
config.phpで設定してやりましょう。
// /system/application/config/config.php :
$config['encryption_key'] = "";
デフォルトでは空白なので、なんらかの文字列を入れてあげましょう。
$config['encryption_key'] = "QEE3Ka2A9ABYhY4dU2VIQau8";
» セッションクラス : CodeIgniter ユーザガイド 日本語版
6. PHPのエラー表示を消す
デフォルトがE_ALLになっているので0を入れてあげましょう。
// /index.php :
error_reporting(0);
7. プライベートメソッドを使う
コントローラ内のメソッドは基本的に全てアクセス可能ですが、
プライベートな物としてコントローラの中でのみ使いたい、
そんな時はメソッドの頭にアンダースコアをつけてあげると、
外部からのアクセスが出来なくなり、ブラウザでアクセスしても404となります。
class Hoge extends Controller {
/* 中略 */
function public_method (){ // アクセス可能
}
function _secret_method (){ // アクセス不可(404)
}
}
アクセスされる事が好ましくないメソッドは、
プライベートメソッドとして宣言しておきましょう。
以上です。
日々注意しつつ、安全なアプリケーション制作をこころがけましょう!
(と、主に自分に言い聞かせる)
コメント