※ 本記事は2017年6月22日に公開されたものです。
SQLインジェクション攻撃では、本来アクセス対象でない表からの情報漏えいが発生するだけでなく、全く関係ないSQL文を実行されてしまうものあります。
前回のエントリでも利用したSQLインジェクションが起きるWEBアプリケーションの検索条件に以下の文字列を入力するとどうなるでしょうか?
'; drop table addrbook --
以下のSQL文が生成され、実行されます。
select name from dbsecdemo.addrbook where name like '%'; drop table addrbook --%'
最後の「–%’」はコメントとして無視されるため、セミコロンで区切られた2つのSQL文となるのが分かります。単純に表を検索して結果を示すアプリで、まさかのDROP TABLE文がデータベースに送信されてしまいます。このように複数のSQL文を1命令にまとめたものを「複文(Multiple Statement)」と呼びます。Oracle Databaseでは基本的に複文をサポートしていないため、下記のようにエラーになりますが、複文をサポートしている環境ではSQLインジェクション攻撃によって想定外の表へのデータ改ざんや破壊が可能になるケースもあります。

ほかのデータベースで複文が利用できるかどうかは「SQL 複文」などで検索して確認してみてください。
SQLインジェクションで攻撃者がアクセスできる対象はそのアプリケーションが利用しているデータベースユーザーがアクセス権限を持っているものです。最小権限の原則の徹底が必要な理由はここにあります。万が一アプリケーションが利用しているデータベースユーザーにDBAロールやSELECT ANY TABLEのような強力なシステム権限が付与されている場合、データベースの中のすべてのデータが漏えいしてしまう危険があります。アプリケーション用のユーザーにそんなに強い権限を付与してしまうことなんてないと思われる方もいるかもしれません。しかし、残念ながら多くのお客様の本番環境でこのような強力な権限が付与されていることがDBSATを利用したセキュリティ・アセスメントサービスから事実としてわかっています。
アプリケーションが利用する表の所有者とアプリケーションから接続するユーザーを分けたほうがよいと第16回の「アプリケーション用のユーザー」で紹介しました。これも参照しかしないアプリケーションでSQLインジェクションが発生した場合、最小限の表への参照権限しか付与していないユーザーであれば、情報漏えいの被害は最小限に抑えられますが、もし表の所有者で接続していた場合、データを書き換えられたリアプリケーションで利用しているそのほかのすべての表の情報まで漏えいしてしまいます。商品カタログ参照アプリケーションで細かな条件で検索できるように複雑なプログラミングをした結果、SQLインジェクションが発生してしまうとしましょう。もし、商品カタログ用の商品データのみ参照できるデータベースユーザーを作成してそのユーザーで接続していた場合には被害の範囲はすべての商品データが参照されてしまうだけに限定されます。しかし、商品カタログを含む購買システムの表の所有者として接続していた場合には、すべての顧客情報が漏えいしてしまったり、発注データが書き換えられてしまったりする可能性もあります。
ここまで、SQLインジェクション対策として、以下のことを紹介してきました。
- エラー情報を表示しない
- エラーが発生したことを監査ログなどから検知し対策する
- アプリケーションはバインド変数を利用する
- アプリケーション用のユーザーに過度の権限を付与しない
これらの対策はSQLインジェクション以外の攻撃にも有効な対策になりますのでぜひ実施していただければと思います。
次回ももう少しSQLインジェクションの話を続けたいと思います。
