SQLインジェクションは、SQLクエリ内のユーザー入力を処理するアプリケーションにとって重要な脅威のままです。 攻撃者は脆弱性を活用して悪意のあるコマンドを注入し、データベース全体を侵害する可能性があります。この記事では、PHPでのSQL注入を防ぐための堅牢な方法について詳しく説明しています。
SQL注入脅威を理解する
未検証のユーザー入力がSQLクエリに直接影響する場合、SQLインジェクションエクスプロイトが発生します。 たとえば、
<code class="language-php">$userInput = $_POST['user_input']; mysql_query("INSERT INTO users (username) VALUES ('$userInput')");</code>
$userInput
'; DROP TABLE users; --
コア原則は、SQLクエリ構造からデータを分離することです。準備されたステートメント(またはパラメーター化されたクエリ)は、次のことでこれを達成します
クエリ/データ分離:データベースサーバーは、データ値とは独立してSQLクエリを解析します。 文字列としてのデータ:
データ:すべてのデータは、悪意のあるSQLコードを中和する文字通り文字列として扱われます。PDO(PHPデータオブジェクト)を使用する
(php 8.2以降):
<code class="language-php">$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name'); $stmt->execute(['name' => $name]); foreach ($stmt as $row) { // Process each row }</code>
および
:
execute_query()
2。 データベース接続のベストプラクティス
<code class="language-php">$result = $db->execute_query('SELECT * FROM employees WHERE name = ?', [$name]); while ($row = $result->fetch_assoc()) { // Process each row }</code>
pdo:prepare()
execute()
最適なセキュリティのためにエミュレートされた準備されたステートメントを無効にします:
<code class="language-php">$stmt = $db->prepare('SELECT * FROM employees WHERE name = ?'); $stmt->bind_param('s', $name); // 's' denotes a string parameter $stmt->execute(); $result = $stmt->get_result(); while ($row = $result->fetch_assoc()) { // Process each row }</code>
mysqli:
堅牢なエラー報告を有効にして、文字セットを指定します:3。 追加のセキュリティ上の考慮事項
<code class="language-php">$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);</code>
ダイナミッククエリ:準備されたステートメントがデータパラメーターを処理する間、クエリ構造自体をパラメーター化することはできません。動的クエリの場合、許可された値を制限するためにホワイトリストを使用してください
結論<code class="language-php">mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); $dbConnection = new mysqli('localhost', 'username', 'password', 'database'); $dbConnection->set_charset('utf8mb4');</code>
以上が準備されたステートメントとパラメーター化されたクエリは、PHPアプリケーションでのSQL注入をどのように防ぐことができますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。