スポンサーリンク
目次
SQLインジェクションとは
SQLインジェクションとは、入力フォームなどから入力した「SQL文を含む文字列」で、アプリケーションが想定していないSQL文を実行させ、データベースの情報を不正操作するサイバー攻撃の一種です。
次の図は、SQLインジェクションのイメージ例です。
- SQLインジェクション対策していないWebサイトに対し、悪意のある攻撃者が「SQL文を含む文字列」を入力して検索や登録を行う。
- 悪意のある攻撃者が入力した「SQL文を含む文字列」が実行される。
- データベースの情報が不正操作される。
SQLインジェクションの攻撃例
[攻撃例1] コメントアウトでSQL文を不正操作
よくあるログイン画面です。「ID」と「パスワード」が一致しなければログインできません。
しかし、「SQLインジェクション対策」をしていないと、「ID」と「パスワード」を知らなくてもログインできてしまう可能性があります。
その攻撃方法とは、「ID」に以下の文字列を入力してログインするだけです。※パスワードは未入力で問題ありません。
1' or '1' = '1';--
前提として以下のSQL文が利用されているとします。このSQL文で画面から入力された「ID」と「パスワード」がデータベースのユーザー情報に存在するか確認し、存在すればログイン成功、存在しなければログイン失敗と判断します。
SELECT id,pass FROM login_user WHERE id='入力されたID' AND pass='入力されたパスワード';
このSQL文に先ほどの「ID」と「パスワード」を当てはめると、次のSQL文が作られます。
SELECT id,pass FROM login_user WHERE id='1' or '1' = '1'-- AND pass='';
まず「id」の条件が"1" または"1 = 1"という条件になっているので、結果は必ずtrueです。
そしてSQL文で「-- 」はコメントアウトを表します。そのためパスワードが一致するかを確認するための条件文「-- AND pass='';」はコメントとして扱われ無視されます。
スポンサーリンク
[攻撃例2] サブクエリでSQL文を不正操作
会員登録画面などの入力フォームです。今回は「名前」と「メールアドレス」を登録する画面があるとします。
まず各項目に、以下を入力し登録します。
名前:山田太郎', (select user_password from user_password where id='1' limit 0,1)) -- おわり
住所:aaa@co.jp
前提として以下のINSERT文が利用されているとします。
INSERT INTO users (name,mail_address) VALUES ('入力された名前','入力されたメールアドレス')
このSQL文を使い、画面で入力した「名前」と「メールアドレス」が「users」テーブルに登録します。
また、他人のパスワードを管理している「user_password」テーブルを用意します。このデータを「SQLインジェクション」の攻撃で盗み取ることを目的とします。
※通常パスワードはソルトやストレッチングを実施した「ハッシュ値(パスワードハッシュアルゴリズム)」で、データベース内に格納するのが一般的ですが、ここではあえて平文で登録しています。
id | user_id | user_password |
1 | 1 | password |
INSERT文に画面から入力された「名前」と「メールアドレス」を当てはめると、以下のようなSQL文が作られます。
INSERT INTO users (name,mail_address) VALUES ('山田太郎', (select user_password from user_password where id='1' limit 0,1)) -- おわり','aaa@co.jp')
- カラム:name → 画面から入力された「山田太郎」が登録されます。
- カラム:mail_address→ 「select user_password from user_password where id='1' limit 0,1」という文字列が入っています。この文字列は、ユーザーパスワードTBL(user_password)から「id = 1」の条件と一致する「user_password」を取得するサブクエリです。
- その結果、カラム:mail_address→ 「password」が登録されます。
- そして、INSERT文の最後にある「-- おわり','aaa@co.jp')」という文字列。これは「-- 」から後ろはコメントアウトという意味です。
結果、実際に実行されたINSERT文(コメントアウト部分を除く)は、以下と同じです。
INSERT INTO users (name,mail_address) VALUES ('山田太郎', (select user_password from user_password where id='1' limit 0,1))
そして、登録内容を閲覧する画面で登録データを見ると、メールアドレスの所に「password」が表示され、他人の個人情報を奪い取る事に成功しています。
-
【SQLインジェクション】INSERT文への攻撃例
続きを見る
[攻撃例3] セミコロンでSQL文を不正操作
商品の検索画面などの入力フォームです。今回は「商品名」で検索する画面があるとします。
そして「商品名」を完全一致で検索するSQL文を使用します。
SELECT * FROM item_info WHERE item_name = '入力された商品名';
ここで商品名に以下を入力して検索します。
'; DELETE FROM item_info WHERE 'A' = 'A
SELECT文に画面から入力された「商品名」を当てはめると、以下のようなSQL文が作られます。
SELECT * FROM item_info WHERE item_id = ''; DELETE FROM item_info WHERE 'A' = 'A'
これで「SELECT * FROM item_info WHERE item_id = ''」と「DELETE FROM item_info WHERE 'A' = 'A'」の2つのSQL文が作られました。
なぜなら、セミコロン「;」を使うことで、SQLを複数のSQL文を連結できるからです。
結果、「item_info」テーブルの全データが削除されてしまいました。
スポンサーリンク
SQLインジェクションの被害事例
発生年 | 内容 |
2011年 | ソニーグループに対する「SQLインジェクション」による攻撃が発覚し、個人情報が流出した可能性があることを発表。流出した個人情報は氏名、住所、Eメールアドレス、生年月日、PlayStation®Network/Qriocity™パスワード、PlayStation®NetworkオンラインID。 |
2016年 | 日販アイ・ピー・エスのウェブサーバが「SQLインジェクション」による攻撃を受け、同社が運営する「CLUB JAPAN」「MagDeli」で最大13万1936件分の顧客情報が流出。流出情報の大半は会員のメールアドレスやIDだが、約30件のクレジットカード情報も同時に流出した可能性があることを発表。 |
2019年 | 株式会社釣りビジョンがSQLインジェクション」による攻撃を受け個人情報が流出した疑いがあることを発表。流出した情報は「メールアドレス:5万1,345人」「メールアドレス、氏名:7,629人」「メールアドレス、氏名、住所:4,682人」 |
SQLインジェクションの対策方法
スポンサーリンク
[対策1] SQL文の組み立ては「プレースホルダ」で実装する
SQLインジェクションの一般的な対策方法は、「プレースホルダ」を使いSQL文を組み立てることです。
プレースホルダによる組み立てとは、パラメータ部分を「?」などの記号で示しておき、後から実際の値を機械的な処理で割り当てる方法です。
以下は、Java における「プレースホルダ」の例です。
ps = conn.prepareStatement("INSERT INTO users (name,address) VALUES (?,?)");
ps.setString(1, name);
ps.setString(2, address);
パラメータを「プレースホルダ」で指定することで、入力された文字列は「ただの文字列」と判断され、SQLインジェクションによる攻撃を防げます。
[対策2] エスケープ処理を行う
SQL 文を構成する要素には、キーワード、演算子、識別子、リテラルなどがあります。
要素 | 例 |
---|---|
キーワード(予約語) | SELECT FROM WHERE AND |
演算子など | = >= , |
識別子 | a b c atable name age |
リテラル | '入力値' 10 |
SQL 文の組み立てを文字列連結により行う場合は、リテラル内で特別な意味を持つ記号文字をエスケープ処理します。(たとえば、「'」→「''」、「\」→「\\」等)
特殊な意味を持つ記号文字をエスケープすることで、SQLインジェクションによる攻撃を防げます。
[対策3] WAF(Web Application Firewall)の導入
WAF(Web Application Firewall)とは、Webアプリケーションの脆弱性を突いた攻撃からWebアプリケーションを保護するセキュリティ対策の一つです。
このWAFを利用するのも、有効なSQLインジェクション対策です。