addslashes ではなく Prepared Statement でSQL文字列をエスケープ

SQL文を作る際、とりあえずどの方法がより強く、より簡易なSQLインジェクション対策なのか調べていたのですが、どうやら addslashes には穴があるらしく、Prepared Statement か、または mysql_real_escape_string() などのデータベース専用エスケープ関数を使用するのがよいらしいとの記事を発見。
PHP 利用時に Shift_JIS で addslashes() によるエスケープ処理に SQL インジェクション可能な穴
addslashesによるエスケープ処理は止めましょう
addslashesは使っていい?使っちゃダメ?

とりあえず Prepared Statement でやってみようかなと。
調べてメモ。


・query() メソッドでの例

$sql = “SELECT * FROM (テーブル名) WHERE (カラム名) = ?”;
$result = $db->query($sql, array(“(?へ渡す値)”));

$placeholder = array(“(?へ渡す値)”)
$sql = “SELECT * FROM (テーブル名) WHERE (カラム名) = ?”;
$result = $db->query($sql, $placeholder);

$placeholder = array(“(1個目の?へ渡す値)”, “(2個目の?へ渡す値)”)
$sql = “SELECT * FROM (テーブル名) WHERE (カラム名) = ? OR (カラム名) = ?”;
$result = $db->query($sql, $placeholder);

・prepare()/execute() メソッドを使用した例

$sql = “SELECT * FROM (テーブル名) WHERE (カラム名) = ?”;
$sth = $db->prepare($sql);
$result = $db->execute($sth, array(“(?へ渡す値)”));

・prepare()/execute() メソッドを使用し、プレースホルダへ2つの配列を渡し、2回クエリを実行させる例

$placeholder = array(array(‘a’,’b’,’c’), array(‘d’,’e’,’f’));
$sql = “INSERT INTO (テーブル名) VALUES (?, ?, ?) “;
$sth = $db->prepare($sql);
$result = $db->execute->executeMultiple($sth, $placeholder);

query() メソッドと prepare()/execute() メソッドの違いは、「エラー処理やリソースの開放などの処理」も違うらしいのだが、よくわからなかった。SELECT など単一のクエリであれば、query() で、いいかしら?・・とりあえず単一のクエリは query() で、INSERTやUPDATEなど複数回実行のクエリは prepare()/execute() でいくことにする。

*プレースホルダは、SQL関数や テーブル名、カラム名などを値として与えることはできない。それらは prepare() の段階で指定してやる必要があるそうです。

PHP データベース編 非SELECT文の実行(日曜プログラミング講座)
PEAR マニュアル 導入 – 準備と実行 — SQL 文を準備し、実行する
prepareとexecuteでDB操作(php spot)
MDB2のプリペアードステートメント記述メモ(PHPのテクメモ)

——————————————————-
■20070427追記■
——————————————————-
んー?「一部のPrepared Statements すらも駄目」??
いろいろ考えつつやらなあかんなぁ・・。

addslashes() による SQL 文字列のエスケープ回避問題
PHP 利用時に Shift_JIS で addslashes() によるエスケープ処理に SQL インジェクション可能な穴

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です