PHP Webサイトを開発する場合、ユーザーログイン関数はほぼ不可欠な部分です。ただし、ユーザー入力が誤って処理されている場合、SQLインジェクション攻撃に対して脆弱です。 MySQLI :: STMT_INITは、 MySQLI拡張機能によって提供される方法であり、前処理ステートメントを使用したSQL注入から効果的に防止できます。この記事では、特定の例を使用して、それを使用して安全なログイン認証メカニズムを実装する方法について説明します。
SQLインジェクションは、悪意のあるSQLステートメントを入力フィールドに注入することにより、攻撃者が元のクエリロジックをタンピングする攻撃技術です。たとえば、SQLを直接スプライスする場合:
$sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";
攻撃者はユーザー名またはパスワードとして「または「1」= '1を入力できます。そのため、クエリは常に真であり、認証をバイパスできます。
mysqli :: stmt_initは、 mysqli_stmtオブジェクトの初期化に使用されます。これは、前処理ステートメントを実装する最初のステップです。 SQLをユーザー入力と厳密に区別することができ、それにより注射攻撃を効果的に防止できます。
安全なログインフォームの検証の例は次のとおりです。
<?php
// データベース接続
$mysqli = new mysqli("localhost", "db_user", "db_password", "my_database");
// 接続を確認してください
if ($mysqli->connect_errno) {
die("接続に失敗しました: " . $mysqli->connect_error);
}
// ユーザー提出ユーザー名とパスワード
$username = $_POST['username'];
$password = $_POST['password'];
// プリプロセシングステートメントオブジェクトを初期化します
$stmt = $mysqli->stmt_init();
// 書く SQL クエリステートメント,使用 ? プレースホルダー
$sql = "SELECT id, password_hash FROM users WHERE username = ?";
// 準備ステートメント
if ($stmt->prepare($sql)) {
// バインドパラメーター(s 急行 string タイプ)
$stmt->bind_param("s", $username);
// 実行ステートメント
$stmt->execute();
// 結果を取得します
$stmt->bind_result($user_id, $password_hash);
// 結果があるかどうかを判断します
if ($stmt->fetch()) {
// パスワードを確認します(データベースが保存されていると仮定します password_hash() 結果)
if (password_verify($password, $password_hash)) {
echo "正常にログインします,ようこそユーザー ID:$user_id";
// セッションまたはジャンプをセットアップします,例えば:
// header("Location: https://m66.net/dashboard.php");
} else {
echo "エラーパスワード";
}
} else {
echo "ユーザー名は存在しません";
}
// 緊密な声明
$stmt->close();
} else {
echo "SQL ステートメントの準備に失敗しました: " . $mysqli->error;
}
// 接続を閉じます
$mysqli->close();
?>
mysqli :: stmt_initを使用してbind_paramを使用して、前処理ステートメントを使用して、SQL注入攻撃を効果的に防ぐことができます。特にデータベース操作が関係している場合は、事前処理ステートメントを開発に常に使用するために、ユーザー入力を処理するために使用する必要があります。さらに、 password_hash()やpassword_verify()などの関数を使用して、パスワードセキュリティを強化する必要があります。
ログインシステムまたはユーザー認証モジュールを構築している場合は、最初にこの方法を使用してください。これは、従来の文字列スプライシングよりもはるかに安全です。