広告 セキュリティ

SQLインジェクションとは | 具体的な攻撃例と対策方法

SQLインジェクションって言葉をよく聞きますが、どういうモノなんですか?
Webサイトの脆弱性を狙ったサイバー攻撃の一種だよ。
データベースに命令するSQL文を不正操作して、データベースに保存されている個人情報などを盗み取る攻撃ですよね。
そうだね。本記事ではSQLインジェクションの具体的な攻撃例や被害例、対策などを分かりやすく説明していきます。

スポンサーリンク

SQLインジェクションとは

SQLインジェクションとは、入力フォームから入力した「SQL文を含む文字列」で、アプリケーションが想定しないSQL文を実行させることにより、データベースを不正操作するサイバー攻撃の一種です。

SQLインジェクションとは

上記は、SQLインジェクションのイメージ図です。SQLインジェクション対策をしていないWebサイトに対し、悪意のある攻撃者が「SQL文を含む文字列」で検索や登録を行います。

その結果、アプリケーション側が想定していない「悪意のある攻撃者」のよる不正操作された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文が利用されているとします。このSQL文で画面から入力された「名前」と「メールアドレス」が「users」テーブルに登録されます。

INSERT INTO users (name,mail_address) VALUES ('入力された名前','入力されたメールアドレス')

 

また他人のパスワードを管理している「user_password」テーブルを用意します。このデータを「SQLインジェクション」の攻撃で盗み取ることを目的とします。

※通常パスワードはソルトストレッチングを実施した「ハッシュ値」でDBに格納するのが一般的ですが、ここではあえて平文で登録しています。

iduser_iduser_password
11password

 

INSERT文に画面から入力された「名前」と「メールアドレス」を当てはめると、以下のようなSQL文が作られます。

INSERT INTO users (name,mail_address) VALUES ('山田太郎', (select user_password from user_password where id='1' limit 0,1)) -- おわり','aaa@co.jp')
  1. カラム:name → 画面から入力された「山田太郎」が登録される。
  2. カラム:mail_address→ 「select user_password from user_password where id='1' limit 0,1」という文字列が入っています。この文字列は、ユーザーパスワードTBL(user_password)から「id = 1」の条件と一致する「user_password」を取得するサブクエリです。
  3. その結果、カラム:mail_address→ 「password」が登録されます
  4. そして、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インジェクション
【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インジェクション対策」は非常に重要なんだ。

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インジェクション対策となります。

helpful