公開日:2007年9月26日
独立行政法人情報処理推進機構
セキュリティセンター
本ページの情報は2007年9月時点のものです。
記載の資料は資料公開当時のもので、現在は公開されていないものも含みます。
SQL注入は、プログラムがパラメータを埋め込んでSQL文を組み立てる場合に、攻撃者がそのパラメータに特殊記号(記号)を含ませたSQLコマンドを与えることで、データベースの不正操作が可能となる脆弱性、またはその脆弱性に対する攻撃をいう。
SQL注入攻撃の対策について、重要となるポイントを中心に以下に記述する。詳細については、Webアプリケーション編の第6章 入力対策「SQL注入」を参照されたい。
SQL注入攻撃を成立させないようにする対策には次の4つが考えられる。
プログラムに渡された値が正しい形式であるかどうかを厳密に検査することによって、攻撃パターンの侵入を防ぐものである。
文字種、桁数等が限定されているデータ項目については高い効果が期待できる。ただし、「任意の長さの通信文」のように文字種や桁数を限定できないデータ項目はその限りでない。
文字列定数 '...' 中に入り込むとSQL文の構文が改変されるおそれのある特殊記号を無害化するか、排除するものである。SQL文では多くの記号が使われるが、とくに対処が必要なのは次の3種類である。
シングルクォート「'」と逆スラッシュ「\」は、それぞれ「''」「\\」のように各文字を2個並べることによって、文字列定数 '...' の中で特殊な意味を持たないようにすることができる。
セミコロン「;」は、この記号がそのままSQL文の構文の中に埋め込まれてマルチプルステートメントが構成されることを防ぐ必要がある。
プリペアドステートメントを用いると、文字列連結演算を用いることなくSQL文の構文の中に値を埋め込むことができる。この方法には、ほかに「プレースホルダ」「変数バインド」等の呼び方もある。
次のようなステップでSQL文への値の埋め込みと実行を行う。
ここで注意しておきたいこととして、プリペアドステートメントのソース文字列の中にユーザ入力データを組込むと、せっかくの対策効果が台無しになるということが挙げられる。
アプリケーション側でSQL文の文字列を組み立てずに済ませるもうひとつの方法として、DBアクセスをすべてストアドプロシジャ呼出しで実装するというやり方がある。
アプリケーションで必要となるDBアクセスパターンごとに、DBエンジン側にストアドプロシジャを用意し、アプリケーションからはこれらのプロシジャにパラメータを渡すというものである。ストアドプロシジャ用のプログラミング言語の中で、SQLの構文とパラメータ要素が明確に識別され処理されるため、SQL文の構文が変えられることはほとんどないと期待される。
シフトJIS、UTF-8等のマルチバイト文字コードが使われる場面では、エスケープ処理に支障が生じることがある。
次の対策が必要である。
処理系によってはプリペアドステートメントの実装が不十分な場合がある。APIの内部で特殊記号のエスケープ処理を行うことによって動作を模擬しているようなケースである。そして、そのエスケープ処理が十分でないことが考えられる。
プリペアドステートメントによる対策方法を採用する際、データベースエンジン側でSQL文ソースコードが処理されてSQL文の構文が確定することを確認する。プリペアドステートメントの実装が十分でなければ、アプリケーション側で特殊記号対策を行う。
SQL注入攻撃の対策には、次の4つがある。入力検査、特殊記号対策、プリペアドステートメントの利用、ストアドプロシジャによる実装である。採用を考慮する順序は、ストアドプロシジャ、プリペアドステートメント、特殊記号対策の順である。入力検査は常に行う。