SQLインジェクションとは?Webアプリの重大な脆弱性とその対策
SQLインジェクション(SQL Injection)とは、ユーザーの入力を悪用して、意図しないSQL文を実行させる攻撃のことです。
適切に対策しないと、データの盗み見、改ざん、削除など重大な被害につながる恐れがあります。
攻撃の仕組み
SQLインジェクションは、ユーザー入力をSQL文にそのまま組み込んでいる場合に発生します。
例:脆弱なコード
$id = $_GET["id"];
$sql = "SELECT * FROM users WHERE id = $id";
$result = mysqli_query($conn, $sql);
このコードに ?id=1 OR 1=1
と入力されると、以下のようにすべてのユーザー情報が取得されてしまいます:
SELECT * FROM users WHERE id = 1 OR 1=1
主な被害例
- パスワードの漏洩
- 顧客情報の改ざんや削除
- ログイン認証の突破(管理者として不正ログイン)
安全な対策方法
@ プリペアドステートメント(PDO)を使う
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->bindValue(":id", $_GET["id"], PDO::PARAM_INT);
$stmt->execute();
A 入力チェック(バリデーション)
数字だけを受け付ける場合:
$id = filter_input(INPUT_GET, "id", FILTER_VALIDATE_INT);
B エスケープ処理(最終手段)
mysqli_real_escape_string()
などを使って入力値を無害化することも可能ですが、プリペアドステートメントの方が安全です。
絶対に避けたいコード例
// 悪い例:SQL文に直接変数を埋め込む
$sql = "DELETE FROM users WHERE id = " . $_POST["id"];
このような書き方は危険なので、必ずプリペアドステートメントを使用してください。
まとめ
- SQLインジェクションは深刻なセキュリティ脅威
- プリペアドステートメントで根本的に防げる
- 入力チェックやエスケープ処理も補助的に行う
- 決してSQL文に直接ユーザー入力を埋め込まない
SQLインジェクションは、対策すれば完全に防げる攻撃です。
安全なアプリケーション開発のために、常に「プリペアドステートメント+バリデーション」を意識してコーディングしましょう。