- 2006年10月20日 12:13
- セキュリティ技術
セキュアドの午後2で、SQLインジェクションに関する問題が出題されていたので、少しまとめておこうかと思います。
SQLインジェクション(SQL-Injection)は、直訳すると「SQLの挿入」という意味になります。
簡単に説明すると、WEBで入力した値を元にSQLを組み立てるようなプログラムがあったとします。
極端なプログラムをC#で書くとすると、
string sqltext = "SELECT * FROM USER_TABLE WHERE USER_ID = '" + User.Text + "' AND PASSWARD = '" + Password.Text + "'";
などというコードがあったとします。(ログイン画面用を想定しています)
そこで、入力用のテキストボックスに
User.Text ← "Hoge"
Password.Text ← "' OR '1'='1"
と入れると、生成されるSQLは以下のようになりますね。
SELECT * FROM USER_TABLE WHERE USER_ID = 'Hoge' AND PASSWARD = '' OR '1'='1'"
そうすると、USER_TABLEの全件が対象となってしまいます。
プログラムで1件だけ取得することを前提としている場合には、先頭のレコードのユーザでログインすることになります。
もしも先頭レコードが管理者権限だったら(最初に管理者を登録するシステムは多いと思うので、可能性は高い)、たったこれだけの手法で管理者権限が奪われることになります。
この攻撃は上記のとおり、非常に簡単な手法なのですが、実際に対策を実施しているサイトは少ないとされています。
セキュアドの午後2では、この問題が発覚する前に「エラー画面にSQL文が表示された」という兆候が現れていました。(まあ試験なので)
プログラマの視点からすると、デバッグ時の効率を考えSQL文を表示したのでしょうが、これは極めて危険な考え方です。
なぜなら、攻撃者に攻撃するためのヒントを教えるようなものだからです。
(多少の知識があれば、表示されている内容からデータベース構造の予想がつきます)
テーブルが分かっている場合、
Password.Text ← "';DELETE FROM USER_TABLE WHERE '1'='1
と入力すると、ユーザを全削除することも可能になってしまいます。
デバッグ時に表示するのはいいとしても、リリースバージョンでは表示しないように設定すべきでしょう。
ログファイルに出力している場合、そのログファイルは外部からアクセスできないようにしておく必要があります。
さて、実際のプログラムでの対策方法ですが、大きく分けて2つの手法があります。
・SQL制御用のタグをサニタイズする
・パラメータクエリを使用する
[SQL制御用のタグをサニタイズ]については、クロスサイトスクリプティング対策と似た考え方ですが、「'」を「''」のように二重化することでデータベースサーバ側で文字列として認識してくれるようになります。('だけでなく、他の文字列もサニタイズが必要ですが、データベースによって方法が多少異なります。)
[パラメータクエリを使用]は、最良の方法だと思いますが、IN句が表現できないなどの問題も存在します。
IN句の取り扱いについては、サニタイズの手法と組み合わせるか、テーブル形式のXMLをパラメータにセットできるデータベースであれば結合演算させることで同じ結果を求めることが可能です。
パラメータクエリの利点として、セキュリティ以外にも速度が速くなるなどの効果が得られる場合もあります。
いずれにしても、プログラマは知っておく必要があり、事故が起こってから知らなかったでは済まない事態になることも少なくありません。
テストを行う際にも、この点を押さえた攻撃テストを行う必要があります。
- Newer: 【情報セキュリティ】クロスサイトスクリプティング
- Older: サイト名について
Comments:0
Trackbacks:0
- TrackBack URL for this entry
- http://magicbox.sakura.ne.jp/mt/mt-tb.cgi/178
- Listed below are links to weblogs that reference
- 【情報セキュリティ】SQLインジェクション from IT試験受験日記