[PHP-users 32370] Re: PHPを使ってのPostgresqlについて
Yasuo Ohgaki
yohgaki @ ohgaki.net
2007年 7月 4日 (水) 01:43:00 JST
おはようございます。大垣です。
kanonbell さんは書きました:
> こんばんは。
>
>>> $hoge = $_REQUEST['hoge'];
>>> $whereSQL = "WHERE abc LIKE '%$hoge%'";
>> 2つエスケープ漏れがあります。
>>
>> まず、クエリに渡す全ての変数はpg_escape_string(またはpg_escape_bytea)で
>> エスケープしなければなりません。PEARのescapeメソッドを使えば良いです。
>
> 個人的には、クエリに変数を渡す際にはPrepared Statementするのがいいと
> 思ってます。
> PostgreSQLの場合は
>
> pg_prepare
> http://jp.php.net/manual/ja/function.pg-prepare.php
> pg_execute
> http://jp.php.net/manual/ja/function.pg-execute.php
pg_queryの代わりに使うならpg_query_paramsが最も簡単にコードの書き換え
ができると思います。
私はプリペアード文のハッシュ値をステートメント名としてプリペアードクエリ
を実行してステートメントが存在しない場合にハッシュ値をステートメント名に
してプリペアする関数やメソッドを使う方法が好みです。
>
> このあたりでしょうか。
>
> とりあえずPHPでSQLを操作する練習って段階ならともかく、ちゃんと実装って
> 段階になるならSQLインジェクション対策は必須になるでしょうし、変数ひとつ
> ひとつエスケープするよりこっちのが楽な気もするので。漏れにくいし。
変数は全部エスケープした方が良いです。数値でも
$sql = "SELECT * FROM table WHERE id = '". pg_escape_string($connection, $_GET['id']). "';";
と言った感じです。普通は$_GET['id']はバリデーションコードで整数の文字列であ
ることが確認されていると思いますが、それでもエスケープは全ての変数に対して
行うべきです。
SQLインジェクションの原因の多くは「整数のはずだったのに...」といった理由なの
で全てエスケープすればこのようなミスは無くなり、問題の発見(エスケープ漏れ)も
簡単になります。
おっしゃる通りプリペアードクエリを利用すればセキュリティ的には全てエスケープ
するのと同じことなのでプリペアードクエリが利用できる場合はプリペアードクエリ
で十分です。
>
> Prepared Statementは本来は何度も実行されるクエリの速度向上を目的と
> したもので、滅多に呼ばれないならマイナスになっちゃう可能性がありますけど、
> いまどき気にするほどのコストじゃないでしょうし。。
>
> 変数個別にエスケープするやり方の方がこういうメリットがあるよ!とか
> あったら教えてくださいませ。
私も基本的にはプリペアードステートメントをお勧めします。しかし、
ライブラリによってはサポートされていません。比較的新しいZend_DB
(Zend FrameworkのActiveRecordパターンの実装)でさえプリペアード
ステートメントになっていません。
PEAR_DBもPostgreSQLのプリペアードステートメントはサポートしてい
なかったと思うのでescapeメソッドを使う方法が最も自然なコーディング
だと思います。PEAR_DBは使わないのでもしかしたらプリペアードクエリ
を上手に使う方法もあるのかも知れません。
> 楽さんはとりあえず使い始めたところ、ってあたりなのかなと言う気もするので、
> 最初からPrepared StatementはSQLの使い方理解しにくいとかは
> ありそうな気もしますけれど。
SQLインジェクション対策としてはプリペアードクエリを利用する事
で9割ほどの問題は解決できると思っていますが、残り1割ほどは解決
できないです。
ライブラリがサポートしていなかったり、ORMのWHERE句部分が指定可能
な場合にはエスケープが必須であったりします。
プリペアードクエリは使えばよいだけなので、私はSQLインジェクション
対策を紹介する場合、エスケープする方法を詳しく紹介するように心掛け
ています。エスケープする方法を詳しく解説した方が結果として安全な
コードを書ける可能性が高くなると思っています。
--
Yasuo Ohgaki : yohgaki @ ohgaki.net : http://www.ohgaki.net/
PHP-users メーリングリストの案内