「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > PHP Anti-SQLインジェクション:事前補償されたステートメントとパラメーター化されたクエリの詳細な説明

PHP Anti-SQLインジェクション:事前補償されたステートメントとパラメーター化されたクエリの詳細な説明

2025-03-12に投稿されました
ブラウズ:285

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

php

でのSQL注入を防ぐ

ユーザー入力が正しく処理されず、SQLクエリに挿入されていない場合、SQLインジェクションの脆弱性が発生します。このリスクを理解するには、次の例を検討してください。

$unsafe_variable = $_POST['user_input'];

mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");
このシナリオでは、ユーザーが

値に似た値を悪意に掲載する場合、になります。

`table`(` column`)values( 'value'); - ')
INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')

ミキシングテクニック:

SQLインジェクションを防ぐためのセキュリティプラクティスは、使用しているデータベースに関係なく、SQLからデータを分離することです。これは、データがデータとして扱われ、SQLパーサーによるコマンドとして解釈されないことを保証することを意味します。これを達成する最も効率的な方法は、前処理ステートメントとパラメーター化されたクエリを使用することです。

事前に処理されたステートメントとパラメーター化されたクエリ:

] プリプロセシングステートメントでは、SQLクエリとパラメーターをデータベースサーバーに個別に送信し、データベースが組み合わせを処理できるようにします。これにより、移転前にデータがPHPによって解析されないことを保証することにより、悪意のあるSQLインジェクションの試みが防止されます。

実装オプション:

前処理ステートメントを実装する2つの主な方法があります:

  1. pdo(php data object):

    ]] これは、サポートされているすべてのデータベースドライバーで動作する一般的なアプローチです。使用の例は次のとおりです。

    $ stmt = $ pdo-> prepare( 'select * from Employees Where Where name =:name'); $ stmt-> execute(['name' => $ name]); foreach($ stmt as $ row){ //処理行 }
    $stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
    $stmt->execute([ 'name' => $name ]);
    
    foreach ($stmt as $row) {
        // 处理行
    }
  2. mysqli(mysqlの改善拡張):

    ]] MySQLデータベースの場合、MySQLIを使用できます。 PHP 8.2から始めて、

    execute_Query()

    メソッドを使用して、パラメーターを準備、バインドし、SQLステートメントを1つのステップで実行できます。 $ result = $ db-> execute_query( 'select * from Employees Where name =?'、[$ name]); while($ row = $ result-> fetch_assoc()){ //処理行 }

    $result = $db->execute_query('SELECT * FROM employees WHERE name = ?', [$name]);
    while ($row = $result->fetch_assoc()) {
        // 处理行
    }

    $ stmt = $ db-> prepare( 'select * from Employees Where name =?'); $ stmt-> bind_param( 's'、$ name); $ stmt-> execute(); $ result = $ stmt-> get_result(); while($ row = $ result-> fetch_assoc()){ //処理行 }

    $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()) {
        // 处理行
    }
    mysql以外のデータベースを使用する場合、
  3. pg_prepare()

pg_execute()]など、ドライバー固有の代替案が存在します。 正しい接続設定:

] 接続を確立する場合、パフォーマンスとセキュリティを改善するために、前処理ステートメントのシミュレーションを無効にすることが重要です。

PDO接続:

$ 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);

$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);

mysqli_report(mysqli_report_error | mysqli_report_strict); $ dbconnection = new mysqli( '127.0.0.1'、 'username'、 'password'、 'test'); $ dbconnection-> set_charset( 'utf8mb4');

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // 错误报告
$dbConnection = new mysqli('127.0.0.1', 'username', 'password', 'test');
$dbConnection->set_charset('utf8mb4'); // 字符集
前処理ステートメントを実装し、接続を正しく設定することにより、SQLインジェクション攻撃を効果的に防止し、データベースアプリケーションのセキュリティと整合性を確保できます。

最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3