ホームページ制作/SEO対策なら株式会社サイバーブレーンへ

 03-5961-5681 平日10:00~19:00

 2017-01-16

sqlインジェクションのパターンを集める

どんなインジェクションがあるのか集めてみる、集める理由は「論より証拠」という事で、SQLインジェクションを利用した不正アクセスを実感する為です。
収集方法は、引数の妥当性チェックをすべて行い、エラーがある場合は、WEBサーバー環境変数を単純に電子メールにて送信する方法を取りました。
GETの場合は、環境変数から引数を参照できるので、そこからインジェクションを探ります。
POSTの場合は、POSTデータの全てをメールに含めます。
(PUTやDELETEを許可している場合も基本は外部からくる引数、ヘッダも含めてすべて妥当性チェックをしてエラーがある場合に、収集するという基本は同じになります。)

SQLインジェクション対策 -- MySQL

まずは、MySQLの場合のインジェクション対策。
1.引数が数字の場合
数字かをチェックして、数字でなければエラー処理をしてDBにアクセスはしない。

2.文字列の場合
当たり前ですが、必ずエスケープ処理をする。

3.DATEやTIMEの場合
日付や時間の妥当性チェックをする。
妥当性エラーの場合は、もちろんDBにアクセスしないでエラー処理をする。
これが意外とやっていないケースが多いです。
やらなくても文字列と同じようにエスケープ処理をすればインジェクションにはならないと思いますが、
そもそも不要なDBリソースを利用しない事が重要だと考えます。

4.その他
サイズチェックや、文字列でも指定カラムに絶対に存在しない文字列がある場合は、それもチェックする。
そしてエラー処理をして不要なDBアクセスを避けることが重要。

収集結果のまとめ

コンテンツIDによって出力するページ内容を切り替えているPHPプログラムとMySQLの場合を例にします。
/xxx/?id=6というコンテンツがあった場合に
id=6%27%20aND%20%278%27%3D%278
というアクセスがありました。
idの値がURLデコードされて、プログラムにわたりますので、プログラムでこのIDの値を参照すると
6' aND '8'='8
となるので、SQLのWHEREにこれをそのままセットすると
$sql ="SELECT contnet, create_date FROM content_tbl WHERE id=" . $_GET['id'] となり、
これは、SELECT contnet, create_date FROM content_tbl WHERE id=6' aND '8'='8
となり、これはエラーになります。

では、以下の場合は、
$sql ="SELECT contnet, create_date FROM content_tbl WHERE id="' . $_GET['id'] . "'";
SELECT contnet, create_date FROM content_tbl WHERE id='6' aND '8'='8'
となり、idが6のコンテンツを取り出すだけなので、害はありません。
しかし、これが通るとインジェクションの可能性を考慮して、union を使って バージョンを求めたり、
そのほか色々な情報を引き出そうとします。
id=6%27%20union%20select%20unhex%28hex%28version%28%29%29%29%20%2d%2d%20%27x%27%3d%27x
これは、
SELECT contnet, create_date FROM content_tbl WHERE id=6' union select unhex(hex(version())) -- 'x'='x
となり、unionでのカラム数が合わないのでエラーになります。
そこで、
id=6%27%20union%20select%20unhex%28hex%28version%28%29%29%29%2cNULL%20%2d%2d%20%27x%27%3d%27x
id=6' union select unhex(hex(version())),NULL -- 'x'='x
として、NULLを追加しながらカラム数を合わせてきます。
sqlインジェクションが可能な場合は、情報を引き出すか、有益な情報が無ければDBのファイル出力を利用して、
踏み台プログラムを埋め込もうとしてきます。

プログラミングする際に、エスケープ処理をしないという事は考えにくいのですが、うっかりミスを狙ってきているのだと思います。
最低でも、
$sql ="SELECT contnet, create_date FROM content_tbl WHERE id="' . sql_escape_function($_GET['id']) . "'";
としているでしょうから、この場合、エスケープ処理+シングルクオートによる文字列としての扱いになっているので、
数値項目の暗黙の型変換が行われて単純にidが6の条件としてレコードを取得します。
しかし、明らかに不正な値を引数にしてきている場合は、DBアクセスをしないように、「SQLインジェクション対策」を
しっかりとすべきです。

~この記事の著者~

セキュリティ対策に関するご相談はこちら

 03-5961-5681 平日10:00~19:00

メールフォーム

あなたが
サイトに
求める要素
あなたがサイトに求める0要素