現在の位置: ホーム> 最新記事一覧> SQL注入は処理されず、結果は異常です

SQL注入は処理されず、結果は異常です

M66 2025-05-28

MySQLデータベース操作にPHPを使用する場合、開発者はMySQLI拡張機能で関連する関数を使用してクエリを実行し、結果セットを処理することがよくあります。たとえば、 mysqli_query()をmysqli_resultオブジェクトで使用して、クエリ結果を簡単に取得できます。ただし、SQLステートメントを構築するときに入力パラメーターが適切に処理されない場合、SQLインジェクションの問題を引き起こすのは簡単で、異常なクエリ結果、データの漏れ、さらにはシステムの故障につながります。

1。問題シナリオの例

ユーザー情報を照会するページがあるとしますが、コードは次のとおりです。

 <?php
$conn = new mysqli("localhost", "root", "password", "mydb");

$username = $_GET['username']; // ユーザー入力から
$sql = "SELECT * FROM users WHERE username = '$username'";

$result = $conn->query($sql);

if ($result && $result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "ユーザー: " . $row["username"] . ",郵便: " . $row["email"] . "<br>";
    }
} else {
    echo "未找到ユーザー";
}
$conn->close();
?>

ユーザーが次のURLを入力した場合:

 https://m66.net/user.php?username=admin' OR '1'='1

その後、SQLステートメントは次のようになります。

 SELECT * FROM users WHERE username = 'admin' OR '1'='1'

これにより、認証条件をバイパスし、すべてのユーザーのレコードを返します。

2。異常なクエリ結果の原因の分析

mysqli_resultオブジェクトを使用して結果セットを処理する場合、返されたデータはSQLステートメントの実行結果に依存します。ステートメントに違法な条件が注入され、結果の結果が予期しないデータを含む場合、プログラムロジックは次のように偏っています。

  • 誤差条件:上記の例のように、ロジックは$ result-> num_rows> 0が真であると判断しますが、実際には、返されたデータがすべてである可能性があります。

  • データリーク:攻撃者は、他のユーザーのプライバシー情報を読むために条件を構築できます。

  • 混乱した後続の操作:許可判断を下し続ける場合、結果に基づいてレコードやその他の操作を変更する場合、結果はさらに深刻になります。

3。解決策

1。準備されたステートメントを使用します

sqlインジェクションは、 prepare()bind_param()を使用することにより、完全に防ぐことができます。

 <?php
$conn = new mysqli("localhost", "root", "password", "mydb");

$username = $_GET['username'];
$stmt = $conn->prepare("SELECT * FROM users WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();

$result = $stmt->get_result();
if ($result && $result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "ユーザー: " . $row["username"] . ",郵便: " . $row["email"] . "<br>";
    }
} else {
    echo "未找到ユーザー";
}

$stmt->close();
$conn->close();
?>

前処理ステートメントを使用した後、パラメーターが自動的に逃げてタイプチェックされ、ソースからの注入を防ぎます。

2。ユーザー入力をフィルター

セキュリティ保証の補足として、前処理を置き換えることはできませんが、すべてのユーザー入力は必要な検証の対象となる必要があります。例えば:

 $username = filter_input(INPUT_GET, 'username', FILTER_SANITIZE_STRING);

または、違法な文字やキーワードを拒否するカスタムフィルタリングロジック。

3。データベースアクセスレイヤーの統一されたカプセル化

さまざまなモジュールの開発者からの繰り返しのミスを回避するために、データベースアクセスロジックを統一クラスまたは機能にカプセル化し、常に内部で前処理を使用し、SQLステートメントのスプライシングを禁止することをお勧めします。

4。概要

MySQLI_RESULT自体はSQLインジェクションの問題を引き起こしませんが、UNESCAPED SQLステートメントで使用すると、クエリ段階で深刻な隠れた危険をもたらします。ユーザーの入力が関与している限り、クエリ操作がどれほど無害であっても、前処理ステートメントを使用する必要があります。

覚えておいてください:**単なるユーザー名であっても、入力を信用しないでください。 ** M66.NETなどのオンラインサービスでは、これらの基本的なセキュリティ対策が無視されている場合、データは少なくとも異常であり、最悪の場合はシステムのクラッシュとデータが漏れます。

すべてのPHP開発者が合理的な保護対策を講じ、コードレベルからのSQLインジェクションを排除することは、揺るぎない責任です。