PHPでのSQLインジェクション対策 - プレースホルダ編: まとめ

PHPでのSQLインジェクション対策 - プレースホルダ編: まとめ

プレースホルダに関する注意

boolean型のカラムにfalseをそのまま設定できるのはMDB2のみ

プレースホルダに対する値として、PHPのboolean型のfalseを指定できるのは、MDB2で、かつプレースホルダの型として'boolean'を指定した場合のみです。

その他の場合にfalseを指定しても、この値は空(ゼロ長)の文字列に変換されてしまいます。これは現時点での修正予定はなさそうです。

http://bugs-beta.php.net/bug.php?id=37031

pg_****または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などを使用するエスケープ・クォート編を参考にしてください。


(2011年6月6日 更新)