|
===================================== 〔語彙分解〕的な部分一致の検索結果は以下の通りです。 ・ インジェクション : [いんじぇくしょん] (n) injection, (n) injection
SQLインジェクション()とは、アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のこと。また、その攻撃を可能とする脆弱性のことである。 SQLに別のSQL文を「注入(inject)」されることから、「ダイレクトSQLコマンドインジェクション」もしくは「SQL注入」と呼ばれることもある。 == 原理 == アプリケーションが入力値を適切にエスケープしないままSQL中に展開することで発生する。 次のようなSQLを発行することを考える。 ここで入力値に " t' OR 't' = 't " という文字列を与えた場合を考えると、SQL文は次のように展開される。このSQL文では条件が常に真となるため、nameカラムの値にかかわらず、全レコードが選択される。このような攻撃は、入力値が1つだけのものには限られない。 これを応用したものに、SELECTの条件式にデータベース内の情報を確認するようなサブクエリーを含ませ、その抽出の成否によって本来参照することのできないテーブル名などのデータベース内の情報を知るといった、ブラインドSQLインジェクションと呼ばれる手法も存在する。例えば、「テーブル名の1文字目がaのテーブルは存在するか?」「aで始まり2文字目がbのテーブルは存在するか?」などの情報を確認するサブクエリーを含め、その抽出の成否を丹念に集めていけば、テーブル名や項目名を確認できる。 また、複数のSQL文を注入することによるデータの破壊や改竄、ストアドプロシージャを実行されることによる情報の漏洩や改竄、OSコマンドの実行などを引き起こすこともできる場合がある。 SQLインジェクションは、入力値を適切にエスケープすることで防ぐことができる。上述の文字列中への展開では、メタ文字 ' を (単一引用符2つ)にエスケープすることにより、次のようなSQLになり、意図されたとおりnameカラムが "t' OR 't' = 't " という値を持つレコードが選択される。(単一引用符を2回連続して記述すると、ひとつの ' という文字リテラルとして認識される。) ただし、データベースシステムによっては、単一引用符以外の囲み文字を用いて文字列リテラルを示すことができるものが存在する。例えば、MySQLでは動作モードによっては二重引用符を文字列の囲み文字として使用可能である。このような環境下で、上記のようなSQL文の生成を行うプログラム中で二重引用符を囲み文字を用いているなら、二重引用符をエスケープする必要がある。 他には、文字列リテラル中の単一引用符を表現する方法が複数存在するものもある。例えばMySQLやPostgreSQLのバージョンや設定次第では、エスケープ文字としてバックスラッシュを使用して特殊文字を表現することが可能である。この方法を用いると \' や \047 (注:047は単一引用符の8進表記)という文字列が文字列リテラル中の単一引用符を表すことになる。このようなデータベースシステムでは、単純に単一引用符を二重化するだけではSQLインジェクション対策としては不充分である。例えば入力値に "\' OR 1=1 -- " という文字列を与え、そこに含まれる単一引用符を単純に二重化すると、上述のSQLは以下のように解釈される。二重化された単一引用符のうち、前者は前置されたバックスラッシュと合わさって文字列リテラル中の単一引用符を意味することになり、後者は文字列リテラルの終端を意味することになる。ここで -- 以降がコメントと見なされれば、このSQLの条件は常に真となり、SQLインジェクションが成立することになる。つまり、バックスラッシュもエスケープを必要とする。更には、文字コードによっては2バイト目にバックスラッシュが含まれる文字を有するものが存在し、エスケープ処理を行うライブラリによっては日本語をうまく扱えないために、前述のようなエスケープシーケンスとしてバックスラッシュが機能することもありえる。データベースにSQLを発行する言語側の事情により、文字コード変換が自動的に発生することに伴って、前述のようなエスケープシーケンスとしてバックスラッシュが機能することもありえる。 抄文引用元・出典: フリー百科事典『 ウィキペディア(Wikipedia)』 ■ウィキペディアで「SQLインジェクション」の詳細全文を読む スポンサード リンク
|