CodeIgniter ユーザがフォームバリデーションクラスについて知るべき 5つのこと

CodeIgniter には、フォームのバリデーション(検証)のための「フォームバリデーション(検証)クラス」およびフォーム関連の処理のための「フォームヘルパー」が含まれています。

なお、この記事は、CodeIgniter 1.7 および 2.0 〜 2.0.3 に基づいています。

1. フォームバリデーションは $_POST しか処理しない

フォームバリデーションは、フォームの入力値の検証を行うものですが、CodeIgniter 1.x は $_GET を使わない(強制的にクリア)という大胆な仕様だったことが影響し、$_POST しか処理しません。

CodeIgniter 2.0 以降、$_GET も普通に使えるようになっていますが、フォームバリデーションは以前のまま GET メソッドのフォームではそのままでは使えません(1つずつのフィールドをフォームバリデーションにあるメソッドで個別に検証することは可能ですが、$_POST のように $_GET 配列をまとめて検証することはできません)。

むろん、この仕様は変更される予定ではありますが。

2. フォームヘルパーの form_prep() 関数には脆弱性につながるバグがある

form_prep() 関数は、HTML でのエスケープ処理をする関数ですが、バグがありエスケープされないケースがあります。フォームヘルパーの関数は内部的に form_prep() 関数を使っています。

具体的には、CodeIgniter 1.7.2 Formヘルパーの脆弱性 を参照してください。

以前から報告しているバグなのですが、なかなか修正されません。フォームバリデーションのエスケープ処理は複雑でよくわからないくらいですので、簡単に直せない状態になっていて、また、それほど問題も発生しないので放置されているのかも知れません。

3. 検証でエラーになったとき、$_POST の値が微妙にエスケープされる

検証でエラーになった場合のみ、フォームバリデーションの prep_for_form() メソッドでのエスケープ処理が実行されますが、このエスケープ処理が、

  1. 「'」「"」「<」「>」を文字参照に置き換える
  2. stripslashes() でバックスラッシュを削除する

という微妙なものとなっています。「&」は何故かエスケープされません。

なお、$_POST の値のみが処理され、フォームバリデーションクラスが保持する POST データである $_field_data プロパティはそのような処理はされません。

これは、フォームヘルパーの set_value() 関数の値は、$_POST の値と異なる(可能性がある)ということです。

この処理は何か中途半端なのであまり使いたくありません。ユーザ入力の再表示には set_value() を使うことで & もエスケープされた値を出力できます(バグがなければ)ので、$_POST の値や $_POST の値を返す $this->input->post() メソッドの値は使わないほうがいいように思います。

4. 検証ルールを定義し検証処理を実行しないと、set_value() で入力値が取れない

$this->form_validation->set_rules() メソッドなどでフィールドの検証ルールを定義した上で、$this->form_validation->run() メソッドを実行しないと、フォームバリデーションクラスは そのフィールドの POST データを保持しません。

すべてのフィールドの検証ルールをきちんと定義して、run() メソッドで検証処理を実行すれば問題はないのですが、ハマる人がたまにいるようです。

5. 存在しないルール名を指定した場合、検証は通る

デバッグログには以下のようなログが記録されますが、検証自体は通ります。

DEBUG - 2011-07-31 14:33:11 --> Unable to find validation rule: not_exist
DEBUG - 2011-07-31 14:33:11 --> Unable to find validation rule: asd

もし、ルール名をタイプミスした場合、意図せず検証をパスしてしまう可能性があります。デバッグログを確認するか、確実にテストしてください。