概要
SQLインジェクション(SQLi)は、ユーザ入力値がSQL文に直接埋め込まれる実装の欠陥を悪用し、攻撃者が任意のSQL文を実行できる脆弱性です。データベースの不正閲覧・改ざん・削除・認証バイパスなど、影響範囲が広くSC試験でも必ず出題されます。
仕組みと動作原理
基本的な攻撃例
脆弱なコード(文字列連結):
SELECT * FROM users WHERE id = '入力値'
攻撃者が ' OR '1'='1 を入力すると:
SELECT * FROM users WHERE id = '' OR '1'='1'
-- → 常に真になりすべてのレコードが返る
SQLiの分類
| 種類 | 特徴 | 攻撃者が得られるもの |
|---|---|---|
| エラーベースSQLi | DBエラーメッセージから情報を取得 | テーブル名・カラム名・DB種別 |
| ユニオンベースSQLi | UNION で別テーブルの結果を合流 | 任意のテーブルのデータ |
| ブラインドSQLi(ブーリアン) | 条件の真偽でレスポンスが変わる挙動から推測 | 1ビットずつ情報を取得 |
| ブラインドSQLi(時間) | SLEEP() 等で応答時間を観察 | エラーも差異もない環境で利用 |
| 2次SQLi | 入力値がDBに一度保存され、後で別処理でSQL実行時に発火 | 遅延型で検出困難 |
攻撃で可能になること
- 認証バイパス:
' OR 1=1--でパスワードチェックを回避 - データ漏洩:個人情報・ハッシュ化パスワード・機密データの抽出
- データ改ざん・削除:UPDATE・DELETE 文の実行
- ストアドプロシージャの悪用:EXEC xp_cmdshell(MS SQL Server)でOSコマンド実行
対策
根本対策:プリペアドステートメント(バインド変数)
# 脆弱(文字列連結)
query = "SELECT * FROM users WHERE id = '" + user_input + "'"
# 安全(バインド変数)
query = "SELECT * FROM users WHERE id = ?"
cursor.execute(query, (user_input,))
バインド変数は SQL 構造とデータを完全に分離するため、入力値がどんなSQL構文を含んでいても「データ」として扱われます。
| 対策 | 効果 | 備考 |
|---|---|---|
| バインド変数(プリペアドステートメント) | ◎ | 根本対策 |
| ストアドプロシージャ | ○ | バインド変数と併用が望ましい |
| 入力値のエスケープ | △ | 漏れが生じやすく根本対策ではない |
| WAF | △ | 補完的対策。バイパス手法もある |
| エラーメッセージの非表示 | △ | エラーベース SQLi の緩和策 |
| 最小権限の DB アカウント | △ | 被害を局限化 |
SC試験での頻出ポイント
- 根本対策はバインド変数:エスケープや WAF は「補完的」対策として位置付ける
- 2次SQLiの概念:入力値がサニタイズ済みでも、後で別クエリで使われる際に危険
- エラーメッセージを抑制する理由:エラーベース SQLi への情報提供を防ぐ
- DB アカウントの最小権限:攻撃が成功しても DROP TABLE・xp_cmdshell などを実行できないようにする
- ブラインド SQLi の検出の難しさ:正常なレスポンスしか返らない場合でも攻撃可能
よくある誤問・ひっかけパターン
誤り① 「WAF を導入すれば SQLi を完全に防御できる」→ 誤。WAF はバイパス手法が存在し、完全な防御にはなりません。アプリケーション側のバインド変数が根本対策です。
誤り② 「入力値をエスケープすれば SQLi を防げる」→ 基本的には可だが不十分。エスケープは漏れが発生しやすく、バインド変数の方が確実です。マルチバイト文字のエスケープ漏れが過去に問題になった事例もあります。
誤り③ 「ブラインド SQLi は通常の SQLi より危険ではない」→ 誤。応答に差異がなくても時間を使って情報を取得できるため危険度は同等です。
関連用語
- XSS(クロスサイトスクリプティング) — 同じく入力値処理の脆弱性。混同しやすい
- CSRF — SQLi と組み合わせて攻撃が行われることもある
- ファイアウォールとDMZ — WAF はアプリ層の防御として FW と組み合わせて使う
重要キーワード
| 用語 | 説明 |
|---|---|
| バインド変数 | SQL構造とデータを分離してSQLiを防ぐ根本対策 |
| ブラインドSQLi | エラーや出力がない状態で真偽・時間差から情報を抽出する手法 |
| ユニオンベースSQLi | UNION句で任意テーブルの内容を取得する攻撃 |
| 2次SQLi | 保存されたデータが後に別クエリで実行される遅延型SQLi |
| WAF | Webアプリ向けのアプリ層ファイアウォール。SQLi・XSSの補完的対策 |
| 最小権限 | DBアカウントに必要最低限の権限のみを付与して被害を局限化する原則 |