SQLインジェクションとは何か?

From The Joel on Software Translation Project

Revision as of 15:59, 2 November 2006 by Aoki (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Joel Spolsky / 青木靖 訳
2006年11月1日 水曜


私はあるオンラインサイトでユーザ登録しようとしていた。

その登録ページでは、秘密の質問と秘密の答えを入れるようになっている。秘密の質問は"What is aunt Vera's cat's color"(ベラおばさんの猫の色はなに?)にした。質問にアポストロフィが入っているのに文句を言われて、しょうがないのでアポストロフィは取った。

秘密の答えの方には"Aunt Vera doesn't have a cat"(ベラおばさんは猫を飼ってない)と入れた。

そうしたらこんなのが表示された。

1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't have a cat', 'male')' at line 1
(1064: SQLの構文にエラーがあります。MySQLのマニュアルで正しい構文を確認してください。エラーは1行目の't have a cat', 'male')'のあたりにあります。)

これが意味するのは、このプログラマがユーザから受け取った文字列(つまりGETやPOSTのパラメタ)を他のSQLの断片とつなぎ合わせてSQL文を生成しているということだ。

PHPからPostgreSQLを使う例で書いてみよう。

$x = pg_query("select * from accounts where name='" . $_GET["name"] . "'");

(PHPプログラマでない人のために言っておくと、"."は文字列連接オペレータだ。)

私は彼らがそういう書き方をしていることに別に驚かない。プログラミングの本やチュートリアルやドキュメントの多くが、例でそういう書き方をしているからだ。

具合の悪いことにこれは大きなセキュリティホールであり、SQLインジェクションと呼ばれている。

悪意あるユーザはプログラマが開いた文字列を閉じてSELECT文を終わらせ、セミコロン(SQL文の区切り記号)に続けて任意のSQL文を書いて実行させることができる

だから、たとえばユーザが氏名のところに次のように入力すると

foo'; delete * from accounts --

・・・実行されるSQL文はこのようになる。

select * from accounts where name='foo'; delete * from accounts --'

・・・これは見ての通りのことをする。すなわちaccountテーブルのレコードをすべて削除するのだ。

これは非常に一般的に見られる問題なのだ。マイケル・サットンはちょっとした調査プロジェクトを実施して、Webアプリケーションの11.3%にSQLインジェクション脆弱性があるという結果を得た。


(オリジナル: What's a SQL Injection Bug?)

戻る

Personal tools