某大手企業向けのCMSシステムでセキュリティ監査があって、弊社納入のシステムで、ちょっと指摘をいただきました。

実際には、SQLインジェクションが実行可能だったわけではなく、お客様に土下座なんて事態にも至らなかったのですが、知らないことがあったのは事実なので、素直に今後は気を付けようと思う今日この頃。

内容は、以下の通り。全て必須対策だそうです。

コンパイル済みSQLを使用する

$db = pg_connect('dbname=…');
$result = pg_prepare($db, 'query1',
'SELECT * FROM TABLE1 WHERE CITY = $1 AND AGE >= $2');
$result = pg_execute($db, 'query1', array($city, $age));

これは正直言って関数自体を知りませんでした。
最近の入門書には書いてあるのかもしれませんね。
「ベテランであること」と「スキル」は全く関係ないことを痛感しました。

header関数で文字コードを必ず指定する

header("Content-Type: text/html; charset=UTF-8");

こちらに解説がありました。
結果オーライでやっていましたが、XSS対策の一つになるとは知りませんでした。

文字列のエスケープ

pg_escape_string()

これは知ってましたが以下の内容は勉強不足でした。

「’」(シングルクオート)と「\」(バックスラッシュ)のエスケープを実
施している場合でも、文字コードの問題によってSQLインジェクションが発生するケースがあります。
処理系の日本語対応が不十分な場合、シフトJISで2バイト目が「\」(バックスラッシュ)のアスキーコードである「0x5C」になっている文字が入力されると「’」(シングルクオート)が「\(0x5C)」にエスケープされます。
これにより、SQLインジェクションを成立させることが可能となりますので、
対策の際には注意が必要です。
具体的には以下の方法があります。

  • 最新のデータベース接続ライブラリを使用した上で、データベースエンジンにて提供されたエスケープ機能を利用する
  • バインド機構を利用する
  • PostgreSQLの場合は、以下の設定を利用する。この場合円記号「\」のエスケープはしないことに注意。
    backslash_quote = off
    standard_conforming_strings = on

とても勉強になりました。

2009/06/25 追記
徳丸様のご指摘により、standard_conforming_strings = offの部分をonに修正しました。