【cfqueryparam】SQLインジェクションを防ぐ | うたらぼ(アメブロ)

【cfqueryparam】SQLインジェクションを防ぐ

SQLインジェクションとは、

アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のこと。また、その攻撃を可能とする脆弱性のこと。
ウィキペディア参照

例えば、以下のソースがあります。

01: <cfquery name="qry_tmp" dataSource ="dbKaisya">
02: select id,name,address,yubin,mail
03: from M_SYAIN
04: where and id = #url.id#
05: </cfquery>

idで絞り込みたい場合は、URLは以下のようになります(ドメインとプログラム名は適当)。

http://www.hoge.com/index.cfm?id=1

idが100というデータが存在しない場合は、

http://www.hoge.com/index.cfm?id=100

としても、一致するデータはありません。
では、以下のようにするとどうでしょう(%20はスペース)。

http://www.hoge.com/index.cfm?id=100%20or%200=0

なんと!全データを取得してしまいます。
クエリの処理を見てみると、以下のようになりました。

01: select id,name,address,yubin,mail
02: from M_SYAIN
03: where id = 100 or 0=0

where句の意味は、「id=100のデータ、または0=0(true)(すべて)」となります。

これでは意図する結果を得られません。
idは数値のみなので、数値だけを対象としたい。
こんなときにcfqueryparamを使用します。

01: select id,name,address,yubin,mail
02: from M_SYAIN
03: where id = <cfqueryparam value = "#url.id#"
04:                 cfsqltype = "CF_SQL_INTEGER">

再度以下のURLを実行します。

http://www.hoge.com/index.cfm?id=100%20or%200=0

するとurl.idの部分は

100 or 0=0
cfqueryparamで指定した型はintegerなので、url.idの値は該当しません。
エラーとなります。

フォームやURLを使用する場合、入力した値が直接SQLに関係ある場合は、
cfqueryparamを使うほうがよいです。


cfqueryparamのドキュメントはこちらです(cf7)。