SQL文を作る際、とりあえずどの方法がより強く、より簡易なSQLインジェクション対策なのか調べていたのですが、どうやら addslashes には穴があるらしく、Prepared Statement か、または mysql_real_escape_string() などのデータベース専用エスケープ関数を使用するのがよいらしいとの記事を発見。
→PHP 利用時に Shift_JIS で addslashes() によるエスケープ処理に SQL インジェクション可能な穴
→addslashesによるエスケープ処理は止めましょう
→addslashesは使っていい?使っちゃダメ?
とりあえず Prepared Statement でやってみようかなと。
調べてメモ。
$sql = "SELECT * FROM (テーブル名) WHERE (カラム名) = ?";
$result = $db->query($sql, array("(?へ渡す値)"));
$placeholder = array("(?へ渡す値)")
$sql = "SELECT * FROM (テーブル名) WHERE (カラム名) = ?";
$result = $db->query($sql, $placeholder);
$placeholder = array("(1個目の?へ渡す値)", "(2個目の?へ渡す値)")・prepare()/execute() メソッドを使用した例
$sql = "SELECT * FROM (テーブル名) WHERE (カラム名) = ? OR (カラム名) = ?";
$result = $db->query($sql, $placeholder);
$sql = "SELECT * FROM (テーブル名) WHERE (カラム名) = ?";・prepare()/execute() メソッドを使用し、プレースホルダへ2つの配列を渡し、2回クエリを実行させる例
$sth = $db->prepare($sql);
$result = $db->execute($sth, array("(?へ渡す値)"));
$placeholder = array(array('a','b','c'), array('d','e','f'));query() メソッドと prepare()/execute() メソッドの違いは、「エラー処理やリソースの開放などの処理」も違うらしいのだが、よくわからなかった。SELECT など単一のクエリであれば、query() で、いいかしら?・・とりあえず単一のクエリは query() で、INSERTやUPDATEなど複数回実行のクエリは prepare()/execute() でいくことにする。
$sql = "INSERT INTO (テーブル名) VALUES (?, ?, ?) ";
$sth = $db->prepare($sql);
$result = $db->execute->executeMultiple($sth, $placeholder);
*プレースホルダは、SQL関数や テーブル名、カラム名などを値として与えることはできない。それらは prepare() の段階で指定してやる必要があるそうです。
→PHP データベース編 非SELECT文の実行(日曜プログラミング講座)
→PEAR マニュアル 導入 - 準備と実行 -- SQL 文を準備し、実行する
→prepareとexecuteでDB操作(php spot)
→MDB2のプリペアードステートメント記述メモ(PHPのテクメモ)
-------------------------------------------------------
■20070427追記■
-------------------------------------------------------
んー?「一部のPrepared Statements すらも駄目」??
いろいろ考えつつやらなあかんなぁ・・。
→addslashes() による SQL 文字列のエスケープ回避問題
→PHP 利用時に Shift_JIS で addslashes() によるエスケープ処理に SQL インジェクション可能な穴
はてなブックマーク










