Hello there, ('ω')ノ
SQLインジェクションの脆弱性があるアプリケーションでは、UNION
キーワードを使用して他のテーブルのデータを取得 することが可能です。これを 「SQLインジェクション UNION攻撃」 と呼びます。
🔍 UNIONを利用したSQLインジェクションとは?
UNION
を使用すると、2つ以上のSELECT
文の結果を結合 し、1つの結果セットとして取得できます。
例:
SELECT a, b FROM table1 UNION SELECT c, d FROM table2;
このクエリは、table1
の a, b
列と、table2
の c, d
列を結合し、1つの結果セットとして返します。
🎯 UNION攻撃の実行手順
SQLインジェクションを利用して UNION
を挿入し、データベースの別のテーブルから機密情報を取得する 方法を説明します。
1️⃣ UNION攻撃が可能かを確認する
攻撃者は、まず UNION
を使用できるかどうかを確認する必要があります。
対象となるクエリが次のような構造だと仮定します。
SELECT name, description FROM products WHERE category = 'Gifts';
ここに UNION SELECT NULL, NULL--
を試してみます。
https://insecure-website.com/products?category=Gifts' UNION SELECT NULL, NULL--
もし エラーが発生しなければ、UNION
が利用可能であると確認できます。
エラーが発生した場合、カラム数を調整 する必要があります。
2️⃣ カラム数を特定する
ORDER BY
を使用して、もともとの SELECT
文が何列のデータを取得しているかを特定します。
https://insecure-website.com/products?category=Gifts' ORDER BY 1--
https://insecure-website.com/products?category=Gifts' ORDER BY 2--
https://insecure-website.com/products?category=Gifts' ORDER BY 3--
どこかでエラーが発生した場合、その直前の値がカラム数になります。
例えば、ORDER BY 3--
でエラーが出たら、カラム数は 2 です。
3️⃣ 機密情報を取得する
カラム数が2だとわかった場合、管理者のユーザー名とパスワードを取得できる可能性があります。
https://insecure-website.com/products?category=Gifts' UNION SELECT username, password FROM users--
これにより、users テーブルの username と password が取得可能 になります。
🛡 SQLインジェクション UNION攻撃の防御策
1️⃣ プリペアドステートメントを使用する
ユーザー入力を直接SQLクエリに含めないようにする。
$stmt = $pdo->prepare("SELECT name, description FROM products WHERE category = ?"); $stmt->execute([$category]);
2️⃣ ユーザー入力のバリデーションを行う
- 許可リスト(ホワイトリスト)を使用し、指定された値のみ受け付ける
UNION
,SELECT
,--
,'
などのSQL構文をフィルタリング
3️⃣ エラーメッセージを隠す
SQLエラーをユーザーに表示せず、汎用的なエラーメッセージを返す。
✅ まとめ
🎯 攻撃の流れ
1. UNION
が利用できるか確認(UNION SELECT NULL, NULL--
でテスト)
2. ORDER BY
でカラム数を特定
3. UNION SELECT username, password FROM users--
で機密情報を取得
🛡 防御策
✅ プリペアドステートメントを使用する
✅ 入力値のバリデーションを行う
✅ エラーメッセージを隠す
SQLインジェクション UNION攻撃は、データベースの中身を盗み出す強力な手法 です。
しっかりと対策を講じ、アプリケーションのセキュリティを強化しましょう! 🚀
Best regards, (^^ゞ