[ 通常表示 ]  [ 簡易表示 ]  [ シンプル表示 ]

「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典イメージぴよ画像「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

SQLインジェクション

pointこの用語のポイント

point悪いことだよ

pointもしくは、悪いことができる状態(セキュリティ上の欠陥、脆弱性)だよ

pointSQL文の穴埋め部分に変な文章を入れておかしな動きにしてやるぜ攻撃だよ

スポンサーリンク

簡単に書くよ

SQLインジェクションとは

SQL文に対する【焼】肉【定】食型攻撃のこと。
もう少し真面目に書くと

穴埋めになっているSQL文の穴埋め部分に、作った人が意図しない内容を入れることによって、おかしな動きをさせること。もしくは、それができるようになっている状態
です。

image piyo

詳しく書くよ

順番に見ていきましょう。

データベースは「データを入れておく箱」ね。
突っ込んで考えると混乱するかもしれません。
何となくのフィーリングで理解してください。

SQLインジェクション

SQLは「データベースとやり取りするときに使う言葉」です。

SQLインジェクション2

データベースにデータを入れるときは、データベースさんに対して「ちょっと、これを入れておいて」と命令します。
反対にデータベースからデータを取り出すときは、データベースさんに対して「ちょっくら、こんなデータを取り出しておくれ」と命令します。
SQLは、そんな命令をするときに使う言葉です。

SQL文は「SQLを使ったデータベースに対する命令文」です。
クエリ」とも呼ばれます。

SQLインジェクション3

「SQL」と「SQL」は違います。
あまり神経質になる必要はありませんが、区別できるようにしておいてください。

SQLは「言語」です。
SQL文は「命令(文)」です。

SQLインジェクション4

例えば、ピヨ子さんがピヨ太君に日本語で「パン買ってこい!」と命令したとしましょう。

SQLインジェクション5

ピヨ子さんが人間、ピヨ太君がデータベースだとすれば「日本語」が「SQL」です。
「パン買ってこい!な命令」が「SQL文」になります。

それを踏まえて、次にいきましょう。

例外はありますが、一般的なデータベースを使っているシステムでは、SQL文によってデータベースさんとやり取りをしています。

この、システムで使うSQL文ですが、同じような命令を何回もするのが普通です。
例えば、日記システムを考えてみてください。

「今日の日記を取ってきてよ」
「昨日の日記を取ってきてよ」
「一昨日の日記を取ってきてよ」


のように、同じような命令をする機会が少なくありません。

そこで、あらかじめ

「○○の日記を取ってきてよ」

のような、ひな形を用意しておくのです。
そうすると、実際に命令をするときには「○○」の部分を埋めれば済みますよね。
「今日」「昨日」「一昨日」あるいは「3月5日」のような日付を埋めれば、データベースさんは指定した日付の日記を取ってきてくれます。

データベースを使ったシステムというのは、大概、このような工夫が成されています。
そして「○○」の部分に入る情報を、外部から指定できるようにしておくことも珍しくはありません。
日記システムを使う人が「昨日の日記が見たいな~」と言えば「○○」には「昨日」が入りますし「一昨日の日記が見たいな~」と言えば「○○」には「一昨日」が入るような作り方です。

ここまでが前振りです。
いよいよ本題に入ります。

「○○の日記を取ってきてよ」のようなひな形を使ったSQL文による命令において「○○」の部分に作った人が想定していないような内容を入れることにより、誤作動を引き起こす攻撃が「SQLインジェクション」です。
あるいは、そのような攻撃を可能とするセキュリティ上の欠陥(脆弱性)を指す場合もあります。

例えば、そうですね。

ピヨ太君は、趣味でパン屋さんを始めました。

SQLインジェクション6

ピヨ太君のパン屋さんは注文制です。
あらかじめ

「  」パンを「 」個、注文します。

のように書かれた注文用紙があります。

お客さまは、ここに

アン」パンを「3」個、注文します。



カレー」パンを「1」個、注文します。

のように書いてピヨ太君に渡すことによって、パンを買うことができるのです。

ピヨ太君のパン屋さんはそれなりに繁盛しました。
ピヨ太君はあぶく銭でうっはうはです。

SQLインジェクション7

しかし、ピヨ太君の幸せな日々は長く続きませんでした。

ピヨ太君があぶく銭に浮かれていたある日のことです。
イタズラ大好きアクマ君がやってきました。

SQLインジェクション8

アクマ君は、注文用紙に以下のように書いてピヨ太君に渡しました。

フライ」パンを「1」個、注文します。

なんと!
ピヨ太君はパン屋さんで、パンの注文を受けていたはずなのに、いつの間にかフライパンを注文されていました。
ピヨ太君にはフライパンを作る技術がありません。
思わぬ事態にテンパって寝込んでしまいました。

SQLインジェクション9

これをSQL文に対して行うのが、SQLインジェクションです。
あるいは、このような攻撃が行えるようになっている状態のことを指す場合もあります。

なんとなーくのイメージは湧いたでしょうか。

それでは次に、実際のSQL文を使ってSQLインジェクションの例を見てみましょう。

例えば、以下のようなSQL文があったとします。

select * from 社員テーブル where 社員番号='○○';

これは「社員テーブルから社員番号が○○のデータを取ってきてください」な命令のSQL文です。
「○○」の部分には外部から指定した社員番号が入ります。

このSQL文を使うシステムは、仮に社員名簿システムとしましょう。
システムを使う人は、社員番号「1」の人の情報を見たいときは画面の社員番号欄に「1」と入力して「検索」ボタンを押します。

そうすると「○○」に「1」が入り、

select * from 社員テーブル where 社員番号='1';

のSQL文が実行されます。
あとは、結果がデータベースさんから返ってくるので、それを画面に表示すればOKです。

ちなみに、社員番号は一人につき一つで、重複はありません。
つまり

select * from 社員テーブル where 社員番号='○○';

のSQL文を実行して返ってくるデータは1件だけです。

当たり前ですね。

社員番号を指定してデータを取得しているのです。
データベースに保管されているデータは社員番号一つにつき一人です。
よって、社員番号を指定して取得した際のデータは、必ず1件か0件(0件は見つからない場合)になります。

システムを作った人は、そう考えていました。

ところがですね。

イタズラっ子な社員さんが、社員番号欄に

1' or 社員番号 > '0

と入力してしまったのです。

そうすると、実際に実行されるSQL文は

select * from 社員テーブル where 社員番号='1' or 社員番号 > '0';

になります。
プログラムを組む人は分かるでしょうが、このSQL文は「社員番号が1、もしくは社員番号が0より大きい人のデータを取ってきてください」な命令です。

取ってくる対象は「社員番号が1、もしくは社員番号が0より大きい人」です。
社員番号が0より大きい人なんて、たくんさんいますよね。
普通は1から採番するので、全社員が該当するかもしれません。

つまり、返ってくる結果は複数です。
たくさんあります。

これはシステムを作った人が想定していない事態でした。
その結果、システムは止まってしまいました。

おーまいがっ。

このように、穴埋めSQLの穴埋め部分に作った人が想定外の内容を入れてやる攻撃、もしくは、それが可能になっている状態がSQLインジェクションです。
今回の例ではデータの取得に対してイタズラをしましたが、やり方によっては、データを全部消したり、本来見られないはずのデータを見たりできます。
恐ろしい攻撃ですね。

ただし、個人的にはSQLインジェクションはバグ(プログラムのおかしいところ)の仲間だと考えています。
穴埋め部分の「○○」に入る値の入力チェックや特殊文字の置換をきちんとやれば、防げる問題ですよ。

image piyo2

一言でまとめるよ

まぁ「SQLインジェクション」って単語が出てきたら「SQL文の穴埋め部分に変なのを入れておかしな動きにしてやるぜ攻撃、もしくは、それが可能な状態のことなんだな~」と、お考えください。

一番上に戻るよ
スポンサーリンク