ホームページ >データベース >mysql チュートリアル >準備されたステートメントとパラメーター化されたクエリは、PHPでのSQL注入をどのように防ぐことができますか?
PHP での SQL インジェクションを防止
ユーザー入力が適切に処理されて SQL クエリに挿入されない場合、SQL インジェクションの脆弱性が発生します。このリスクを理解するには、次の例を考えてください:
<code class="language-php">$unsafe_variable = $_POST['user_input']; mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");</code>
このシナリオでは、ユーザーが悪意を持って value'); DROP TABLE table;--
のような値を入力すると、クエリは次のようになります:
<code class="language-sql">INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')</code>
これにより、データベースに対する悪意のある攻撃への扉が開かれます。
緩和手法:
どのデータベースが使用されているかに関係なく、SQL インジェクションを防ぐために推奨されるセキュリティ対策は、データを SQL から分離することです。これは、データがデータとして扱われ、SQL パーサーによって決してコマンドとして解釈されないようにすることを意味します。この目標を達成する最も効率的な方法は、準備されたステートメントとパラメーター化されたクエリを使用することです。
プリペアドステートメントとパラメータ化されたクエリ:
プリペアド ステートメントでは、SQL クエリとパラメーターをデータベース サーバーに個別に送信し、データベースがそれらの組み合わせを処理できるようにします。これにより、送信前にデータが PHP によって解析されないようにすることで、悪意のある SQL インジェクションの試みを防止します。
実装オプション:
準備されたステートメントを実装するには、主に 2 つの方法があります:
PDO (PHP データ オブジェクト):
これは、サポートされているすべてのデータベース ドライバーで機能する一般的な方法です。その使用例を次に示します:
<code class="language-php">$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name'); $stmt->execute([ 'name' => $name ]); foreach ($stmt as $row) { // 处理行 }</code>
MySQLi (MySQL 改善拡張機能):
MySQL データベースの場合は、MySQLi を使用できます。 PHP 8.2 以降では、execute_query()
メソッドを使用して、単一のステップで SQL ステートメントの準備、バインド、実行を行うことができます:
<code class="language-php">$result = $db->execute_query('SELECT * FROM employees WHERE name = ?', [$name]); while ($row = $result->fetch_assoc()) { // 处理行 }</code>
PHP 8.1 以前の場合:
<code class="language-php">$stmt = $db->prepare('SELECT * FROM employees WHERE name = ?'); $stmt->bind_param('s', $name); // 's' 表示'字符串'变量类型 $stmt->execute(); $result = $stmt->get_result(); while ($row = $result->fetch_assoc()) { // 处理行 }</code>
MySQL 以外のデータベースを使用する場合は、PostgreSQL の pg_prepare()
や pg_execute()
などのドライバー固有の代替手段があります。
正しい接続設定:
接続を確立するとき、パフォーマンスとセキュリティを向上させるために、準備されたステートメントのエミュレーションを無効にすることが重要です。
PDO 接続:
<code class="language-php">$dbConnection = new PDO('mysql:dbname=dbtest;host=127.0.0.1;charset=utf8mb4', 'user', 'password'); $dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);</code>
MySQLi 接続:
<code class="language-php">mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // 错误报告 $dbConnection = new mysqli('127.0.0.1', 'username', 'password', 'test'); $dbConnection->set_charset('utf8mb4'); // 字符集</code>
結論:
準備されたステートメントを実装し、接続を正しく設定することで、SQL インジェクション攻撃を効果的に防止し、データベース アプリケーションのセキュリティと整合性を確保できます。
以上が準備されたステートメントとパラメーター化されたクエリは、PHPでのSQL注入をどのように防ぐことができますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。