webサイトで情報を検索したり、フォームの入力したりする行為は日常的に行われています。
しかし、これらの操作が危険な攻撃の対象になることがあります。
その中でも「SQLインジェクション」は特に危険な攻撃方法の1つです。
今回は、SQLインジェクションとは何か、その仕組みと防止方法についてまとめていきます。
SQLインジェクションとは
SQLインジェクション(SQL Injection)は、攻撃者が悪意のあるSQL文をデータベースに送り込み、不正にデータを取得したり、改ざんしたりする攻撃手法です。
これにより、個人情報の流出やデータベースの破壊など、重大な被害が発生する可能性があります。
具体例:PHPでのSQLインジェクション
まず、SQLインジェクションがどのように行われるかを具体的な例でみてみます。
以下は、ユーザーの入力をSQLクエリに使用する危険なコードです。
<?php
// ユーザーからの入力を取得
$username = $_GET['username'];
$password = $_GET['password'];
// データベース接続(例)
$conn = new mysqli("localhost", "root", "", "example_db");
// SQLクエリを構築
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
// クエリを実行
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "ログイン成功!";
} else {
echo "ユーザー名またはパスワードが間違っています。";
}
?>
このコードでは‘$_GET[‘username’]’と’$_GET[‘password’]‘の値がそのままSQLクエリに組み込まれています。
例えば攻撃者が以下のようなURLを入力するとします。
http://example.com/login.php?username=admin'--&password=
このURLにより、実際に実行されるSQLクエリは次の様になります。
SELECT * FROM users WHERE username = 'admin'--' AND password = ''
‘–‘はSQLのコメントアウト記号であり、それ以降の部分が無視されます。
これによりパスワードが無効になり、’username‘が’admin‘のユーザーが存在する場合、ログインが成功してしまいます。
SQLインジェクションの防止方法
SQLインジェクションを防ぐためには、以下のような対策を講じる必要があります。
プリペアードステートメントの使用
プリペアードステートメントを使用すると、SQL文とデータが分離されるため、SQLインジェクションを防ぐことができます。
以下は、上記のコードをプリペアードステートメントを用いて書き直した例です。
<?php
// ユーザーからの入力を取得
$username = $_GET['username'];
$password = $_GET['password'];
// データベース接続(例)
$conn = new mysqli("localhost", "root", "", "example_db");
// プリペアドステートメントの準備
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ? AND password = ?");
// 1つ目のパラメータをバインド
$stmt->bind_param("s", $username);
// 2つ目のパラメータをバインド
$stmt->bind_param("s", $password);
// クエリを実行
$stmt->execute();
// 結果を取得
$result = $stmt->get_result();
if ($result->num_rows > 0) {
echo "ログイン成功!";
} else {
echo "ユーザー名またはパスワードが間違っています。";
}
?>
プリペアードステートメントを使用することで、ユーザーからの入力がSQL文の一部として解釈されることを防ぎ、SQLインジェクションのリスクを大幅に防ぐことができます。
入力データの検証とサニタイズ
ユーザーからの入力データは常に検証し、必要に応じてサニタイズすることが重要です。
例えば、電子メールアドレスの形式をチェックしたり、特殊文字をエスケープしたりすることが挙げられます。
最小限の権限を持つユーザーを使用
データベースに接続する際は、必要最低限の権限を持つユーザーを使用することで、万が一攻撃が成功した場合でも被害を最小限に抑えることができます。
まとめ
このようにSQLインジェクション非常に危険な攻撃手段ですが、適切な対策を講じることできちんと防ぐことができます。
今回まとめた対策を実施することで、安全なwebアプリケーションを構築し、データベースを保護することができます。
その他のWebの脆弱性についてさらに詳しく知りたい方はこちら。