General

PDOへの移行はほぼ終了

2008年3月1日

アンケートの結果に従ってPDOを利用することにし、sqlクラスを全面的に書き換えた。次の例のように使うことになる。

$res=sql::query('SELECT * FROM jeans_item WHERE icat=<%catid%>',array('catid'=>$catid));
while ($row=$res->fetch()) core::p($row['ititle']);
もしくは
$res=sql::prepare('SELECT * FROM jeans_item WHERE icat= :catid');
$res->bindParam(':catid',$catid);
$res->execute();
while ($row=$res->fetch()) core::p($row['ititle']);
もしくは
$res=sql::prepare('SELECT * FROM jeans_item WHERE icat= :catid');
$res->execute(array(':catid'=>$catid));
while ($row=$res->fetch()) core::p($row['ititle']);

これで、規約に沿ってコアやプラグインを書いている限り、SQLインジェクションはほぼ100%起こらない。

一箇所非常に悩んだところがあって、それはどうやらPDOのバグに起因するようだ。SQLクエリーのLIMIT節ではプリペアードステートメントによる代入ができない。これは、PHPのバージョンやDBエンジンの種類・バージョンによって出たり出なかったりするバグのようであるが、今日現在のPHP最新バージョン5.2.5でSQLite2.8を使った場合はこのバグが出る(SQLite2.8は、Windows版PHPでは最新)。

バグ回避策として、sqlite::query()メソッドで<%xxx%>に整数値を代入しようとするときは、PDOのプリペアードステートメントを使わずに直接クエリーに書き込むことにした。LIMIT節では整数値しか利用しないためである。整数なら文字コードの違いが原因のSQLインジェクションが起きる可能性もないし、バグが完全に解消されるまではこれでよいだろう。

コメント

コメントはありません

コメント送信