Mach3.laBlog

PHP: CodeIgniterをセキュアに使うチュートリアル

この記事は賞味期限切れです。(更新から1年が経過しています)

PHPフレームワークは数多く公開されておりますが、
中でも個人的にお気に入りなのはシンプル・軽量さが売りのCodeIgniterです。
» CodeIgniter – Open source PHP web application framework
この度Nettuts+でCodeIgniterをセキュアに使うためのチュートリアルが紹介されていました。

※2010/08/07 セッションエンコーディングの項で、キー文字列を入力した例を追記

CodeIgniter

CodeIgniter from Scratch: Security | Nettuts+


こちらがそのチュートリアルビデオなのですが…
35分と大変長いので、要点だけ下にまとめておきます。
ビデオではスクラッチから書いていて大変わかりやすいので、
時間がある時に見ておくと良いと思います!
英語ですが、コードだけ見ていても参考になります。

  1. パラメータに使用される文字を制限する
  2. パスワードエンコーディング
  3. SQLインジェクション対策
  4. クロスサイトスクリプティング対策
  5. セッションエンコーディング
  6. PHPのエラー表示を消す
  7. プライベートメソッドを使う

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)
    }
}

アクセスされる事が好ましくないメソッドは、
プライベートメソッドとして宣言しておきましょう。

以上です。
日々注意しつつ、安全なアプリケーション制作をこころがけましょう!
(と、主に自分に言い聞かせる)

コメント

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

*