← 攻撃手法一覧
Webアプリケーション攻撃OWASP Top 101998年〜現在

SQLインジェクションとは

SQLインジェクションはWebアプリケーションのデータベース操作の脆弱性を悪用した攻撃です。 悪意ある SQL 文をフォームや URL に挿入することで、データベースを不正に操作します。 OWASP Top 10に長年ランクインし続ける最も危険なWeb攻撃の一つです。

目次
1. SQLインジェクションの概要2. 攻撃の仕組み3. SQLインジェクションの種類4. 具体的な攻撃例5. 実際の被害事例6. 脆弱性の発見方法7. 対策・予防方法

1. SQLインジェクションの概要

Webアプリケーションはユーザーからの入力をもとにSQLクエリを組み立ててデータベースにアクセスします。 SQLインジェクションはこの入力値の検証が不十分な場合に、攻撃者が意図しないSQLコマンドを 注入(インジェクション)できてしまう脆弱性です。

情報漏洩
データベース内の全ユーザー情報・パスワード・クレジットカード情報などを盗み出せる
認証バイパス
パスワードを知らなくても管理者アカウントにログインできてしまう
データ改ざん・削除
データベースの内容を書き換えたり、テーブルごと削除したりできる
OS命令の実行
設定によってはデータベースサーバー上でOSコマンドを実行できる場合がある

2. 攻撃の仕組み

ログインフォームを例に、SQLインジェクションの仕組みを説明します。

通常のログイン処理
// ユーザーが入力
username: tanaka
password: password123
// 生成されるSQLクエリ
SELECT * FROM users WHERE username='tanaka' AND password='password123'
SQLインジェクション攻撃
// 攻撃者が入力
username: ' OR '1'='1
password: anything
// 生成されるSQLクエリ(常にTRUEになる)
SELECT * FROM users WHERE username='' OR '1'='1' AND password='anything'
'1'='1' は常にTRUEのため、WHERE句全体がTRUEになりパスワードなしでログインできてしまう

3. SQLインジェクションの種類

クラシックSQLインジェクション危険度:
最も基本的な手法。エラーメッセージや結果がそのまま表示される場合に有効。UNIONを使ってデータを取得する「UNION攻撃」も含まれる。
ブラインドSQLインジェクション危険度:
エラーメッセージが表示されない場合でも、TRUEとFALSEの応答の違いを利用してデータを1ビットずつ推測する攻撃。
タイムベースSQLインジェクション危険度:
SLEEP()などの時間関数を使い、応答時間の差でデータを推測する。画面に変化がなくても攻撃できる。
エラーベースSQLインジェクション危険度:
意図的にエラーを発生させ、エラーメッセージにデータベースの情報を含めて取得する手法。
2次SQLインジェクション危険度:
一度データベースに保存された悪意ある入力が、後でSQLクエリに使われる際に攻撃が発動する。発見が難しい。

4. 具体的な攻撃例

認証バイパス
入力値
' OR '1'='1' --
生成されるクエリ
SELECT * FROM users WHERE username='' OR '1'='1' --' AND password='...'
結果: パスワードなしで最初のユーザー(多くの場合管理者)としてログインできる
全データの取得(UNION攻撃)
入力値
' UNION SELECT username, password FROM users --
生成されるクエリ
SELECT name, price FROM products WHERE id='' UNION SELECT username, password FROM users --'
結果: 全ユーザーのID・パスワードハッシュが取得できる
データベースの削除
入力値
'; DROP TABLE users; --
生成されるクエリ
SELECT * FROM users WHERE id=''; DROP TABLE users; --'
結果: usersテーブルが完全に削除される(「Bobby Tables」攻撃)

5. 実際の被害事例

2008年Heartland Payment Systems(米国)約1.3億件のカード情報漏洩
SQLインジェクションにより米国の大手決済処理会社が攻撃を受け、史上最大規模のクレジットカード情報漏洩事件となった。
2011年Sony Pictures約100万人分の個人情報漏洩
LulzSecグループがSQLインジェクションによりSony Picturesのデータベースから個人情報を盗み出した。
2015年米国人事管理局(OPM)約2,150万人分の機密情報漏洩
SQLインジェクションを含む複数の手法により、連邦政府職員の機密情報が大規模に漏洩した。
2019年国内ECサイト多数クレジットカード情報大量漏洩
日本国内の複数のECサイトがSQLインジェクション攻撃を受け、クレジットカード情報が漏洩。被害件数は合計数十万件に上った。

6. 脆弱性の発見方法

自分のWebアプリケーションにSQLインジェクションの脆弱性がないか確認するためのツールと手法です。

sqlmap自分のシステムのみに使用すること
最も有名なSQLインジェクション自動検出・悪用ツール。合法的なペネトレーションテストで広く使われる。
OWASP ZAP初心者にも使いやすい
OWASPが開発した無料のWebアプリケーション脆弱性スキャナー。SQLインジェクションを含む多数の脆弱性を自動検出できる。
Burp Suite高度なテストが可能
プロのペネトレーションテスターが使う総合的なWebセキュリティテストツール。Community版は無料。
手動テスト自分のサイトのみで実施
入力フィールドに ' や " や ; などの特殊文字を入力してエラーが発生するか確認する基本的な手法。

7. 対策・予防方法

最重要プリペアドステートメント(パラメータ化クエリ)を使用する。入力値をSQLの一部として解釈させない
最重要ORMフレームワーク(Hibernate・Sequelize・SQLAlchemyなど)を使用してSQLを直接書かない
推奨入力値のバリデーション・エスケープ処理を徹底する
推奨データベースユーザーに最小限の権限のみ付与する(最小権限の原則)
推奨エラーメッセージにデータベースの詳細情報を含めない
推奨WAF(Webアプリケーションファイアウォール)を導入してSQLインジェクションのパターンをブロックする
組織向け定期的なペネトレーションテストとコードレビューを実施する
// 脆弱なコード(NG)
query = "SELECT * FROM users WHERE username='" + username + "'"
// 安全なコード(プリペアドステートメント)
query = "SELECT * FROM users WHERE username=?"
cursor.execute(query, (username,))

まとめ

SQLインジェクションは1990年代から存在する古典的な攻撃ですが、現在も最も多く悪用されるWeb攻撃の一つです。 プリペアドステートメントを使うだけで大部分の攻撃を防げるにもかかわらず、 未対策のサイトが後を絶ちません。 Webアプリケーション開発者にとって、SQLインジェクション対策は基本中の基本です。

参考・関連リンク

OWASP - SQL InjectionIPA - SQLインジェクション対策OWASP Top 10