ホームページ > データベース > mysql チュートリアル > 準備されたステートメントとパラメーター化されたクエリは、PHPでのSQL注入をどのように防ぐことができますか?

準備されたステートメントとパラメーター化されたクエリは、PHPでのSQL注入をどのように防ぐことができますか?

Patricia Arquette
リリース: 2025-01-25 22:07:12
オリジナル
158 人が閲覧しました

How Can Prepared Statements and Parameterized Queries Prevent SQL Injection in PHP?

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 つの方法があります:

  1. PDO (PHP データ オブジェクト):

    これは、サポートされているすべてのデータベース ドライバーで機能する一般的な方法です。その使用例を次に示します:

    <code class="language-php">$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
    $stmt->execute([ 'name' => $name ]);
    
    foreach ($stmt as $row) {
        // 处理行
    }</code>
    ログイン後にコピー
  2. 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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート