PHPでのSQLインジェクション対策 - プレースホルダ編: まとめ
プレースホルダに関する注意
boolean型のカラムにfalseをそのまま設定できるのはMDB2のみ
プレースホルダに対する値として、PHPのboolean型のfalseを指定できるのは、MDB2で、かつプレースホルダの型として'boolean'を指定した場合のみです。
その他の場合にfalseを指定しても、この値は空(ゼロ長)の文字列に変換されてしまいます。これは現時点での修正予定はなさそうです。
http://bugs-beta.php.net/bug.php?id=37031pg_****またはPDOで、boolean型の値を設定したい場合、以下のように「t」「f」などの文字列を指定してください。
$res = pg_query_params( $dbconn, 'SELECT * FROM users WHERE is_married = $1', array($is_married ? 't' : 'f') );
条件「IS NULL」のNULLや、CURRENT_****はSQL本体側に
「WHERE カラム名 IS NULL」のような条件を指定する場合、NULLの部分をプレースホルダにすることはできません。CURRENT_TIMESTAMP、CURRENT_DATEといった関数も同様です。例えば以下のような構文はエラーになってしまいます。
$all = $mdb2->extended->getAll( 'SELECT * FROM news' . ' WHERE news_source_no IS :n_s_no' . ' AND publish_timestamp <= :p_ts' . ' AND news_genre = :n_genre', MDB2_PREPARE_RESULT, array( 'n_s_no' => null, 'p_ts' => 'CURRENT_DATE', 'n_genre' => 'technology' ), array( 'n_s_no' => 'integer', 'p_ts' => 'timestamp', 'n_genre' => 'text' ) );
「IS NULL」やCURRENT_****を指定したい場合には、この部分をプレースホルダとしてではなく、SQL本体の中に埋め込んでください。
$all = $mdb2->extended->getAll( 'SELECT * FROM news' . ' WHERE news_source_no IS NULL' . ' AND publish_timestamp <= CURRENT_DATE' . ' AND news_genre = :n_genre', MDB2_PREPARE_RESULT, array('n_genre' => 'technology'), array('n_genre' => 'text') );
PostgreSQL9.1からはSQL標準のエスケープがデフォルトに
バージョン9.1以降ではstandard_conforming_strings = onがデフォルトになります。この場合、あえて E'...' の形式でクォートしない限り、文字列内のバックスラッシュ(\)はエスケープ文字として扱われなくなります。MDB2ではプレースホルダを使用している時でも、実際には文字列をPHPのネイティブ関数(pg_escape_string)でエスケープ/クォートしており、このpg_escape_string関数の挙動はstandard_conforming_stringsの設定によって自動的に切り替わります。プログラムの書き方によってはこの設定値をoffにする必要が生じてくるかもしれません。詳しくはPostgreSQL 9.1 の新機能 「互換性に関する注意」を参照してください。
参考サイト
情報処理推進機構:情報セキュリティ:脆弱性対策:安全なウェブサイトの作り方http://www.ipa.go.jp/security/vuln/websecurity.html
どうしてもプレースホルダを使えない場合には、pg_escape_string、$mdb2->quoteなどを使用するエスケープ・クォート編を参考にしてください。