PHPとMySQLのセキュリティー対策関数の継承

※以前別の場所で書いた文章を備忘的に書き記しておきます。

【投稿年月日】2008-03-04 【ジャンル】PHP/MySQL

 「PHPとMySQLのセキュリティー対策関数」「PHPエスケープ関数の比較一覧」の続き。

 PHPとMySQLのセキュリティー対策関数を使うと、配列に対しても一気に変換できますが、HTML表示やMySQLのquery発行の直前に適用できない可能性もあります。そうなると、間違えが起こりやすくなるので、セキュリティー対策としては十分でないと思われます。
 そこで配列を一気に変換した場合、その配列の各要素がセキュリティー対策済みであることを、明示的に継承する手法を提案します。具体的には「PHPエスケープ関数の比較一覧」の後半部分で言及した、ユーザー定義関数(function)の名前付けのように行ないます。
 
 「PHPとMySQLのセキュリティー対策関数」で言及した関数の「h」や「q」を使って、配列を一括して変換した場合、以下のように「h_」や「q_」をつけた名称を使うことで、セキュリティー対策済みの配列であることを明示します。
$value = array(
 '"PHP"'=>'<span>プログラミング言語</span>',
 '\'MySQL\''=>'<strong>データベース</strong>',
 '"JavaScript"'=>'<span>スクリプト言語</span>'
);
$h_value = h($value);  // 「h」でサニタイズした場合は名称に「h_」をつける。
$q_value = q($value);  // 「q」でサニタイズした場合は名称に「q_」をつける。

 サニタイズした配列をforeach()で展開する場合も同様に、変数に「h_」や「q_」をつけてサニタイズ済みであることを明示します。配列の要素(変数)の名称を少しだけ工夫するだけで、「サニタイズの継承」が実現されるわけです。
foreach($h_value as $h_id=>$h_title) {  // 「h」でサニタイズした配列を展開する場合も名称に「h_」をつける。
 echo '<div>'.$h_id.' : '.$h_title.'</div>';  // 変数に「h」がついているのでクロスサイトスクリプティング対策済み → HTML表示時に安全に使用できる
}
foreach($q_value as $q_id=>$q_title) {  // 「q」でサニタイズした配列を展開する場合も名称に「q_」をつける。
 mysql_query("INSERT INTO d1 VALUES ('".$q_id."', '".$q_title."')");  // 変数に「q」がついているのでSQLインジェクション対策済み → MySQLのquery発行時に安全に使用できる
}

 変数や配列、ユーザー定義関数などの名称に、「h_」がついていたらクロスサイトスクリプティング対策済み、「q_」がついていたらSQLインジェクション対策済みというルールを作って徹底できるならば、その都度セキュリティーの確認をする手間が省けるので、セキュリティーにかけるコストが大幅に削減されるものと思われます。
 万人にお勧めできる方法かどうか微妙ですが、セキュリティー対策の一手法として書き残しておきます。

【参考】

EDIUNET | PHP/MySQL | 独り言 | 提供サービス | JavaScript