どーも。ばぁどです。
前回の記事 Webの脆弱性①超基礎 -XSS編-はこちら。
SQLインジェクション
概要
SQLインジェクションとは、開発者が意図しないSQLを流し込まれてDBの値の改ざん、秘匿情報の閲覧などが可能となってしまう脆弱性です。
実装したアプリケーションが値のエスケープを適切に行なっておらず、入力した値がSQLないで展開されてしまった場合、SQLインジェクションが発生してしまう恐れがあります。
WebアプリケーションとDBはとても親和性が高いです。 例えば通販サイトなどを作ろうと思うと、利用者の情報や商品の情報を管理する必要があります。 それらの情報はサーバー側で管理し、必要に応じて情報を取得、作成、更新、削除などを行います。
また、このDBの操作をするために作られた言語がSQLです。
SQLはSELECT
やINSERT
、UPDATE
、DELETE
などの句があり、それらを扱うことでDBの操作を行います。
通販サイトなどでは、商品の検索機能などがあります。 検索機能が使用される場合、WebアプリとしてはDB側に下記のようなSQLを発行するとします。
SELECT * FROM PRODUCTS WHERE product_name = '★★';
★の部分は、Webアプリケーションから入力された値が入るイメージです。
この場合 ★★に入力された文字列と一致するproduct_name
のデータを持つデータがテーブルから検索されます。
PRODUCTSテーブルの例
カラム名 | 説明 |
---|---|
product_id | 商品を一意に識別するID |
product_name | 商品名 |
product_price | 商品の値段 |
prodcut_detail | 商品の詳細 |
テーブルに入っているデータ
product_id | product_name | product_price | product_detail |
---|---|---|---|
1 | パソコン | 200,000 | 使いやすく、軽量なノートPCです。 |
2 | マウス | 3,000 | 黒、白、赤の三色からお選びいただけます。 |
3 | キーボード | 5,000 | キーボード配列カスタマイズ可能です。 |
★★のWebアプリケーションから入力する値にパソコン
という文字列を入力した場合は、下記のようなSQLが組み立てられ発行されます。
SELECT * FROM PRODUCTS WHERE product_name = 'パソコン';
こうすることで、名前がパソコン
と完全一致するために、パソコンのデータを取得することができます。
情報の取得、値の改ざん
SQLインジェクションが存在すると仮定して、上記のWebアプリケーションからの入力に下記のような値を入力します。
入力値:a' OR 'A' = 'A' ; --
この値を入力することで下記のSQLが構築され発行されます。
SELECT * FROM PRODUCTS WHERE product_name = 'a' OR 'A' = 'A' ; --';
上記の結果が 「商品名がaの商品」(A)
もしくは 「AとAが一致している(True)」(B)
として処理されます。
OR
条件なので、A
とB
のどちらがの結果がTrue
であれば、この条件式の結果はTrue
となります。
WHERE
句がTrue
なのでPRODUCTテーブル全てのデータを取得するという条件になります。
本来であれば、商品名(product_name
)と一致するデータ一件が手に入るSQLを発行しているつもりが、商品データ全てを取得するSQLが発行されてしまいます。
今回はデータの取得が主でしたが、同じようにUPDATE
を用いることでデータの改ざん、DELETE
でデータの削除、SQLインジェクションの場所によってはログイン認証の突破なども行えます。
対策
1. バインド機構を用いる
バインド機構とは、SQLを安全に発効するためにライブラリなどで用いられている機能のことです。
今回例題として扱った値(a' OR 'A' = 'A' --;
)にはシングルクォーテーションが用いられています。
これらの'
(シングルクォーテーション)が、SQL内で展開されており、'
として扱われてしまうことが問題なので、適切に'
をSQL構文の'
として扱われないように実装をする必要があります。
それらは、各言語のライブラリやWebアプリケーションフレームワークが提供しているORマッパー(SQLを発行するライブラリ)などで実装されているので、それらを適切に扱いましょう。
まとめ
- SQLインジェクションとは開発者の意図しないSQLが実行されること
- 対策はバインド機構などを用いてSQLを安全に構築すること