PHPセキュリティ対策:正規化した文字列を取り出す

(1/1)
前回に引き続き、入力値の正規化を行う。今回は文字列を扱う。
ユーザーから入力された文字列をそのまま(または少しだけ加工して)画面に  echo  や  echo  で出力するプログラムを見かける。これは非常に危険である。
まず第一に、入力文字列の中に HTML タグや JavaScript が含まれていると、プログラマは意図していないにもかかわらず、そのまま実行されてしまう。
より危険なのが、入力文字列にスクリプトや CGI が書かれている場合である。プログラムの書き方によっては、そのまま実行されてしまうことがある。下手をすると、パスワードが漏れたり、データベースの内容が改竄されてしまうことがある。
space
そこで今回は、入力された文字列に次のような正規化を施してから扱うプログラムを紹介することにする。
  1. 文字コード変換
  2. 文字列長チェック
  3. 文字エスケープ

space
ページ間での文字化けを解消する」で説明したように、ページ間で日本語文字列を渡す際、環境によっては文字化けが発生してしまう。まず、これを解消するために文字コード変換を行う
space
次に、あらかじめ決められた長さより長い文字列を受け付けないようにする。
データベース登録などの場合、文字列の長さ制限があるため、このようなチェック仕様を設けた。
space
最後の文字エスケープは、前述の HTML タグ、JavaScript、PHP や CGI などのスクリプトの実行を阻止するためのエスケープ処理である。これは、行う/行わないの選択ができるようにした。

サンプル・プログラム

テキストボックスに値を入力し、[送信] ボタンを押下する。
値は POST で渡され、前述の正規化が行われた結果が出力される。

プログラムを実行する

ダウンロード(PHP4/5共用)

サンプル・プログラムの解説:文字列の正規化

0056: /**
0057:  * $_GET または $_POST から正規化した文字列を取り出す
0058:  *    コード変換、文字列長チェック、入力文字エスケープ(任意)
0059:  * @param string $str    文字列
0060:  * @param int $maxlen    最大文字列長(バイト、エスケープ後の長さ)
0061:  * @param string $encode 入力文字列のエンコーディング
0062:  * @param bool $escape   TRUE=入力エスケープを行う/FALSE=行わない
0063:  * @return string 取得値/FALSE:エラー(文字列が長すぎる)
0064: */
0065: function getValidString1($str$maxlen$encode$escape) {
0066:     global $InternalEncoding;
0067: 
0068:     $res = mb_convert_encoding($str$InternalEncoding$encode);    //コード変換
0069:     if ($escape)    $res = htmlspecialchars($res);       //文字列長チェック
0070:     if (strlen($res) > $maxlen)     return FALSE;        //エスケープ処理
0071: 
0072:     return $res;
0073: }

ユーザー関数 getValidString1 にて文字列の正規化を行う。
space
まず、関数  mb_convert_encoding  を使って、文字化けしないようにコード変換を施す。
space
次に、関数  strlen  を使って、文字列長のチェックを行う。
ここではバイト長でチェックしているが、本当に文字列長でチェックしたいのであれば、関数  mb_strlen  を使うと良いだろう。
space
最後に、文字列のエスケープ処理を行う。これは関数  htmlspecialchars  にお任せである。この関数は、'<' を '&lt;' に、'>' を '&gt;' に置き換えてくれるので、HTML タグ、JavaScript、各種スクリプトが実行される可能性はほとんど無くなる。
space
その他の処理は、前回とほぼ同じである。

参考書籍

(この項おわり)
header