Hello there, ('ω')ノ
SQLインジェクションを利用すると、認証を回避し、パスワードなしで管理者アカウントにログインすることが可能になります。この攻撃手法は、「アプリケーションのロジックを破壊する」 という点で非常に危険です。
🛠️ 攻撃対象の認証処理
通常、アプリケーションは次のようなSQLクエリを実行して、入力された ユーザー名とパスワード が正しいかをチェックします。
SELECT * FROM users WHERE username = 'wiener' AND password = 'bluecheese';
このクエリが 一致するレコードを返せばログイン成功 となります。
しかし、SQLインジェクションを使うことで、このチェックをバイパスできます。
🎯 SQLインジェクションによる認証回避
攻撃者はログインフォームに次のような入力を行います。
- ユーザー名:
administrator'--
- パスワード: (空欄)
これにより、アプリケーションが次のようなSQLクエリを実行することになります。
SELECT * FROM users WHERE username = 'administrator'--' AND password = '';
💡 --
はSQLのコメントアウト記号 なので、AND password = ''
の部分は無視され、クエリは次のように処理されます。
SELECT * FROM users WHERE username = 'administrator';
もし administrator
というユーザーがデータベースに存在すれば、パスワードが不要でもログインが成功してしまう わけです。
✅ 結果: 攻撃者は パスワードを知らなくても管理者アカウントにログイン可能 になる。
🚀 別の攻撃方法:OR 1=1 を利用した認証バイパス
攻撃者は、次のような入力を使って、どんなユーザー名でもログインできるようにすることも可能です。
- ユーザー名:
' OR 1=1--
- パスワード: (空欄)
この場合、SQLクエリは次のように変わります。
SELECT * FROM users WHERE username = '' OR 1=1--' AND password = '';
1=1
は常に 真 なので、このクエリは データベース内のすべてのユーザー情報を取得 し、最初に見つかったユーザーとしてログインすることになります。
✅ 結果: どのアカウントにもパスワードなしでログインできる。
🔒 防御策(SQLインジェクションを防ぐ方法)
このようなSQLインジェクション攻撃を防ぐためには、以下の対策が必要です。
1️⃣ プリペアドステートメントを使用する(最重要)
ユーザー入力を直接SQLクエリに組み込まず、バインド変数 を使用することでSQLインジェクションを防ぐことができます。
✅ 安全なコード例(PHP + PDO)
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?"); $stmt->execute([$username, $password]);
この方法では、ユーザー入力がSQL構文として解釈されないため、安全にクエリを実行できます。
2️⃣ ユーザー入力のバリデーションを行う
username
に 英数字のみ許可 する。- SQLの特殊文字(
'
,--
,;
,"
など)をブロックする。
✅ 入力値のバリデーション(PHP)
if (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) { die("Invalid username."); }
3️⃣ エラーメッセージを適切に処理する
- データベースのエラーメッセージをユーザーに直接表示しない。
- 一般的なエラーメッセージ(「認証に失敗しました」など)を返すようにする。
✅ 安全なエラーハンドリング(PHP)
try { $stmt = $pdo->prepare("SELECT * FROM users WHERE username = ? AND password = ?"); $stmt->execute([$username, $password]); } catch (Exception $e) { error_log($e->getMessage()); // ログには詳細を記録 die("Login failed."); }
4️⃣ データベースの権限を最小限にする
- アプリケーションのDBユーザーには、必要最低限の権限のみ を付与する。
SELECT
のみ許可し、DROP
やUPDATE
は制限する。
✅ 安全な権限設定(MySQL)
GRANT SELECT ON shop.users TO 'app_user'@'localhost';
✅ まとめ
🎯 攻撃手法のポイント
1. administrator'--
を入力することで、パスワードなしで管理者アカウントにログイン
2. ' OR 1=1--
を入力することで、どのアカウントにもログイン可能
🛡 防御策(必ず実装すること!)
✅ プリペアドステートメントを使用する(最優先)
✅ ユーザー入力のバリデーションを行う(特殊文字をブロック)
✅ エラーメッセージを適切に処理する(SQLエラーを表示しない)
✅ データベースの権限を最小限にする(SELECT
のみ許可)
SQLインジェクションは、適切な対策を講じることで確実に防ぐことが可能 です。開発の際には、常に 「このコードはSQLiに対して安全か?」 を意識し、安全なアプリケーションを構築しましょう!
Best regards, (^^ゞ