PHP+PostgreSQLでのSQLインジェクション対策

某大手企業向けの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に修正しました。

関連記事

お問い合わせ

システム開発に関するお問い合わせをお待ちしています。
お急ぎの方は、Twitterでどうぞ。
もちろん、このページへのコメントも大歓迎です!


2 Comments

  1. 徳丸 浩 より:

    >PostgreSQLの場合は、以下の設定を利用する。この場合円記号「\」のエスケープはしないことに注意。
    >backslash_quote = off
    >standard_conforming_strings = off

    この文脈だと、standard_conforming_stringsはonにすべきだと思います。

  2. miya より:

    徳丸様はじめまして。
    なるほど、offならバックスラッシュはエスケープされるのですね。
    たしかに、文脈がおかしいようです。
    コピペの間違いかなと思ったのですが、そうではないようなので先方に連絡しておきます。
    結果オーライで問題はなかったのですが、徳丸様のブログを拝見させていただいて、身が引き締まる思いでした。
    貴重なご意見をありがとうございます。

Leave a Reply

Additional comments powered by BackType