プリペアドステートメントによる SQL インジェクションに対する保護
プリペアド ステートメントは、ユーザーが指定したデータからコードを明確に分離することで、SQL インジェクションの脆弱性に対する強力な防御を提供します。
SQL インジェクションの脅威を理解する
SQL インジェクションの悪用は、信頼できないデータが SQL クエリ内に直接埋め込まれた場合に発生します。 この危険な行為により、コードとデータの間の境界線が曖昧になり、攻撃者が悪意のあるコマンドを挿入できるようになります。 簡単な例でリスクを説明します。
<code class="language-sql">$query = "SELECT * FROM users WHERE id = '" . $_GET['id'] . "'";</code>
$_GET['id']
に 1; DROP TABLE users; --
が含まれる場合、結果のクエリは次のようになります。
<code class="language-sql">SELECT * FROM users WHERE id = '1; DROP TABLE users; --';</code>
この悪意のある入力は DROP TABLE users
コマンドを実行し、データベースを破壊する可能性があります。
プリペアドステートメントの仕組み
プリペアド ステートメントは、クエリ構造をデータから分離することでこの脆弱性に対処します。 このプロセスには 2 つのステップが含まれます:
<code class="language-php">$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");</code>
?
はデータのプレースホルダーとして機能します。
<code class="language-php">$stmt->execute([$id]);</code>
データベースは、提供されたデータを使用してプリコンパイルされたクエリを実行します。重要なのは、データが実行可能コードではなくデータとして扱われるため、インジェクション攻撃を防止できることです。
PHP/MySQL の実装
これは、準備されたステートメントを使用した前の例の安全なバージョンです:
<code class="language-php">$stmt = $db->prepare("SELECT * FROM users WHERE id = ?"); $stmt->bind_param("i", $expectedData); // "i" specifies integer data type $stmt->execute();</code>
$expectedData
に悪意のある入力が含まれている場合でも、SQL コードではなくデータ値として扱われます。
重要な考慮事項
準備されたステートメントは非常に効果的ですが、完全な保護を提供するわけではありません。 これらは主にデータ リテラル インジェクションを防ぎます。 識別子 (テーブル名または列名) がクエリ内で動的に構築される場合、追加のセキュリティ対策が重要です。
以上がプリペアドステートメントは SQL インジェクション攻撃をどのように防ぐのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。