



スポンサーリンク
目次
SQLインジェクションとは
SQLインジェクションとは、入力フォームから入力した「SQL文を含む文字列」で、アプリケーションが想定しないSQL文を実行させることにより、データベースを不正操作するサイバー攻撃の一種です。
上記は、SQLインジェクションのイメージ図です。SQLインジェクション対策をしていないWebサイトに対し、悪意のある攻撃者が「SQL文を含む文字列」で検索や登録を行います。
その結果、アプリケーション側が想定していない「悪意のある攻撃者」のよる不正操作されたSQL文を実行してしまうのです。


SQLインジェクションの攻撃例
[攻撃例1] 不正ログイン
よくあるログイン画面です。「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] 情報漏洩
会員登録画面などの入力フォームです。今回は「名前」と「メールアドレス」を登録する画面があるとします。
各項目に以下を入力し登録。
名前:山田太郎', (select user_password from user_password where id='1' limit 0,1)) -- おわり 住所:aaa@co.jp
前提として以下のINSERT文が利用されているとします。このSQL文で画面から入力された「名前」と「メールアドレス」が「users」テーブルに登録されます。
INSERT INTO users (name,mail_address) VALUES ('入力された名前','入力されたメールアドレス')
また他人のパスワードを管理している「user_password」テーブルを用意します。このデータを「SQLインジェクション」の攻撃で盗み取ることを目的とします。
※通常パスワードは「ハッシュ化」してDBに格納するのが一般的ですが、ここではあえて平文で登録しています。
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 → 画面から入力された「山田太郎」が登録される。
- カラム:address → 「select user_password from user_password where id='1' limit 0,1」という文字列が入っています。この文字列は、ユーザーパスワードTBL(user_password)から「id = 1」の条件と一致する「user_password」を取得するサブクエリです。
- その結果、カラム: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文を利用します。
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インジェクション対策となります。